enhance(frontend): shiki v1に移行 (#13138)
* enhance(frontend): shiki v1に移行 * optimize chunks, エラーを握りつぶす * wasmを分離 * バンドルサイズの警告の最小値を650kBに引き上げ * optimize
This commit is contained in:
		
							parent
							
								
									e5876440cb
								
							
						
					
					
						commit
						9e1145df81
					
				|  | @ -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", | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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(), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue