From 9e1145df813a49bcf603f5e1830018eac8c4864d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:05:18 +0900 Subject: [PATCH] =?UTF-8?q?enhance(frontend):=20shiki=20v1=E3=81=AB?= =?UTF-8?q?=E7=A7=BB=E8=A1=8C=20(#13138)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): shiki v1に移行 * optimize chunks, エラーを握りつぶす * wasmを分離 * バンドルサイズの警告の最小値を650kBに引き上げ * optimize --- packages/frontend/package.json | 2 +- .../frontend/src/components/MkCode.core.vue | 21 ++++++------- .../frontend/src/scripts/code-highlighter.ts | 28 +++++++++-------- pnpm-lock.yaml | 30 +++++++------------ scripts/build-assets.mjs | 8 ----- 5 files changed, 37 insertions(+), 52 deletions(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index e7193a27a..d614f7588 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -60,7 +60,7 @@ "rollup": "4.9.6", "sanitize-html": "2.11.0", "sass": "1.70.0", - "shiki": "0.14.7", + "shiki": "1.0.0-beta.3", "strict-event-emitter-types": "2.0.0", "textarea-caret": "3.1.0", "three": "0.160.1", diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue index 8fca3bb15..c655ff416 100644 --- a/packages/frontend/src/components/MkCode.core.vue +++ b/packages/frontend/src/components/MkCode.core.vue @@ -5,13 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only <!-- eslint-disable vue/no-v-html --> <template> -<div :class="['codeBlockRoot', { 'codeEditor': codeEditor }]" v-html="html"></div> +<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }]" v-html="html"></div> </template> <script lang="ts" setup> import { ref, computed, watch } from 'vue'; -import { BUNDLED_LANGUAGES } from 'shiki'; -import type { Lang as ShikiLang } from 'shiki'; +import { bundledLanguagesInfo } from 'shiki'; +import type { BuiltinLanguage } from 'shiki'; import { getHighlighter } from '@/scripts/code-highlighter.js'; const props = defineProps<{ @@ -22,24 +22,25 @@ const props = defineProps<{ const highlighter = await getHighlighter(); -const codeLang = ref<ShikiLang | 'aiscript'>('js'); +const codeLang = ref<BuiltinLanguage | 'aiscript'>('js'); const html = computed(() => highlighter.codeToHtml(props.code, { lang: codeLang.value, theme: 'dark-plus', })); async function fetchLanguage(to: string): Promise<void> { - const language = to as ShikiLang; + const language = to as BuiltinLanguage; // Check for the loaded languages, and load the language if it's not loaded yet. if (!highlighter.getLoadedLanguages().includes(language)) { // Check if the language is supported by Shiki - const bundles = BUNDLED_LANGUAGES.filter((bundle) => { + const bundles = bundledLanguagesInfo.filter((bundle) => { // Languages are specified by their id, they can also have aliases (i. e. "js" and "javascript") return bundle.id === language || bundle.aliases?.includes(language); }); if (bundles.length > 0) { - await highlighter.loadLanguage(language); + console.log(`Loading language: ${language}`); + await highlighter.loadLanguage(bundles[0].import); codeLang.value = language; } else { codeLang.value = 'js'; @@ -57,8 +58,8 @@ watch(() => props.lang, (to) => { }, { immediate: true }); </script> -<style scoped lang="scss"> -.codeBlockRoot :deep(.shiki) { +<style module lang="scss"> +.codeBlockRoot :global(.shiki) { padding: 1em; margin: .5em 0; overflow: auto; @@ -74,7 +75,7 @@ watch(() => props.lang, (to) => { min-width: 100%; height: 100%; - & :deep(.shiki) { + & :global(.shiki) { padding: 12px; margin: 0; border-radius: 6px; diff --git a/packages/frontend/src/scripts/code-highlighter.ts b/packages/frontend/src/scripts/code-highlighter.ts index 957669122..bc05ec94d 100644 --- a/packages/frontend/src/scripts/code-highlighter.ts +++ b/packages/frontend/src/scripts/code-highlighter.ts @@ -1,7 +1,6 @@ -import { setWasm, setCDN, Highlighter, getHighlighter as _getHighlighter } from 'shiki'; - -setWasm('/assets/shiki/dist/onig.wasm'); -setCDN('/assets/shiki/'); +import { getHighlighterCore, loadWasm } from 'shiki/core'; +import darkPlus from 'shiki/themes/dark-plus.mjs'; +import type { Highlighter, LanguageRegistration } from 'shiki'; let _highlighter: Highlighter | null = null; @@ -13,16 +12,19 @@ export async function getHighlighter(): Promise<Highlighter> { } export async function initHighlighter() { - const highlighter = await _getHighlighter({ - theme: 'dark-plus', - langs: ['js'], - }); + const aiScriptGrammar = await import('aiscript-vscode/aiscript/syntaxes/aiscript.tmLanguage.json'); - await highlighter.loadLanguage({ - path: 'languages/aiscript.tmLanguage.json', - id: 'aiscript', - scopeName: 'source.aiscript', - aliases: ['is', 'ais'], + await loadWasm(import('shiki/onig.wasm?init')); + + const highlighter = await getHighlighterCore({ + themes: [darkPlus], + langs: [ + import('shiki/langs/javascript.mjs'), + { + aliases: ['is', 'ais'], + ...aiScriptGrammar.default, + } as unknown as LanguageRegistration, + ], }); _highlighter = highlighter; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2cbad24f..0561e8b01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -797,8 +797,8 @@ importers: specifier: 1.70.0 version: 1.70.0 shiki: - specifier: 0.14.7 - version: 0.14.7 + specifier: 1.0.0-beta.3 + version: 1.0.0-beta.3 strict-event-emitter-types: specifier: 2.0.0 version: 2.0.0 @@ -5951,6 +5951,10 @@ packages: string-argv: 0.3.1 dev: true + /@shikijs/core@1.0.0-beta.3: + resolution: {integrity: sha512-SCwPom2Wn8XxNlEeqdzycU93SKgzYeVsedjqDsgZaz4XiiPpZUzlHt2NAEQTwTnPcHNZapZ6vbkwJ8P11ggL3Q==} + dev: false + /@sideway/address@4.1.4: resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} dependencies: @@ -9297,10 +9301,6 @@ packages: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - /ansi-sequence-parser@1.1.1: - resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} - dev: false - /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -14693,6 +14693,7 @@ packages: /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -18247,13 +18248,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - /shiki@0.14.7: - resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} + /shiki@1.0.0-beta.3: + resolution: {integrity: sha512-z7cHTNSSvwGx2DfeLwjSNLo+HcVxifgNIzLm6Ye52eXcIwNHXT0wHbhy7FDOKSKveuEHBwt9opfj3Hoc8LE1Yg==} dependencies: - ansi-sequence-parser: 1.1.1 - jsonc-parser: 3.2.0 - vscode-oniguruma: 1.7.0 - vscode-textmate: 8.0.0 + '@shikijs/core': 1.0.0-beta.3 dev: false /side-channel@1.0.4: @@ -20019,14 +20017,6 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} - /vscode-oniguruma@1.7.0: - resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} - dev: false - - /vscode-textmate@8.0.0: - resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - dev: false - /vue-component-type-helpers@1.8.27: resolution: {integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==} dev: true diff --git a/scripts/build-assets.mjs b/scripts/build-assets.mjs index 2e1268130..d2dabe853 100644 --- a/scripts/build-assets.mjs +++ b/scripts/build-assets.mjs @@ -35,13 +35,6 @@ async function copyFrontendLocales() { } } -async function copyFrontendShikiAssets() { - await fs.cp('./packages/frontend/node_modules/shiki/dist', './built/_frontend_dist_/shiki/dist', { dereference: true, recursive: true }); - await fs.cp('./packages/frontend/node_modules/shiki/languages', './built/_frontend_dist_/shiki/languages', { dereference: true, recursive: true }); - await fs.cp('./packages/frontend/node_modules/aiscript-vscode/aiscript/syntaxes', './built/_frontend_dist_/shiki/languages', { dereference: true, recursive: true }); - await fs.cp('./packages/frontend/node_modules/shiki/themes', './built/_frontend_dist_/shiki/themes', { dereference: true, recursive: true }); -} - async function copyBackendViews() { await fs.cp('./packages/backend/src/server/web/views', './packages/backend/built/server/web/views', { recursive: true }); } @@ -81,7 +74,6 @@ async function build() { copyFrontendFonts(), copyFrontendTablerIcons(), copyFrontendLocales(), - copyFrontendShikiAssets(), copyBackendViews(), buildBackendScript(), buildBackendStyle(),