From 6587bea226f31f438d76e28d39e7e659e80b5f46 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Thu, 20 Aug 2026 17:29:17 +0800 Subject: [PATCH] Optimize Shiki loading with JavaScript regex engine --- package.json | 1 + .../comment-widget/src/comment-content.ts | 2 +- packages/comment-widget/src/shiki-bundle.ts | 40 +++++++++++++++++++ .../comment-widget/tests/shiki-bundle.test.ts | 37 +++++++++++++++++ packages/comment-widget/vite.config.ts | 11 +++++ pnpm-lock.yaml | 3 ++ 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 packages/comment-widget/src/shiki-bundle.ts create mode 100644 packages/comment-widget/tests/shiki-bundle.test.ts diff --git a/package.json b/package.json index c9ebfe7..06d6bbf 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ }, "packageManager": "pnpm@11.22.0", "dependencies": { + "@shikijs/themes": "^4.4.3", "shiki": "^4.4.3" } } diff --git a/packages/comment-widget/src/comment-content.ts b/packages/comment-widget/src/comment-content.ts index 05d6ee1..ee59e2b 100644 --- a/packages/comment-widget/src/comment-content.ts +++ b/packages/comment-widget/src/comment-content.ts @@ -31,7 +31,7 @@ export class CommentContent extends LitElement { const content = codeblock.textContent || ''; try { - const { codeToHtml } = await import('shiki/bundle/full'); + const { codeToHtml } = await import('./shiki-bundle'); const html = await codeToHtml(content, { lang, diff --git a/packages/comment-widget/src/shiki-bundle.ts b/packages/comment-widget/src/shiki-bundle.ts new file mode 100644 index 0000000..f09ade2 --- /dev/null +++ b/packages/comment-widget/src/shiki-bundle.ts @@ -0,0 +1,40 @@ +import githubDark from '@shikijs/themes/github-dark'; +import { + type CodeToHastOptions, + type CreateHighlighterFactory, + createBundledHighlighter, + createSingletonShorthands, + guessEmbeddedLanguages, + type ShorthandsBundle, + type ThemeRegistration, +} from 'shiki/core'; +import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'; +import { bundledLanguages } from 'shiki/langs'; + +type BundledLanguage = keyof typeof bundledLanguages; +type BundledTheme = 'github-dark'; + +const bundledThemes: Record = { + 'github-dark': githubDark, +}; + +const createHighlighter: CreateHighlighterFactory< + BundledLanguage, + BundledTheme +> = createBundledHighlighter({ + langs: bundledLanguages, + themes: bundledThemes, + engine: () => createJavaScriptRegexEngine(), +}); + +const shorthands: ShorthandsBundle = + createSingletonShorthands(createHighlighter, { guessEmbeddedLanguages }); + +function codeToHtml( + code: string, + options: CodeToHastOptions +): Promise { + return shorthands.codeToHtml(code, options); +} + +export { bundledLanguages, bundledThemes, codeToHtml, createHighlighter }; diff --git a/packages/comment-widget/tests/shiki-bundle.test.ts b/packages/comment-widget/tests/shiki-bundle.test.ts new file mode 100644 index 0000000..c661960 --- /dev/null +++ b/packages/comment-widget/tests/shiki-bundle.test.ts @@ -0,0 +1,37 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { + bundledLanguages, + bundledThemes, + codeToHtml, + createHighlighter, +} from '../src/shiki-bundle.ts'; + +test('highlights code with the JavaScript regex engine', async () => { + const html = await codeToHtml('const answer = 42;', { + lang: 'javascript', + theme: 'github-dark', + }); + + assert.match(html, /