diff --git a/packages/vscode/src/DOCUMENTATION.md b/packages/vscode/src/DOCUMENTATION.md index 72823844..e0de1b91 100644 --- a/packages/vscode/src/DOCUMENTATION.md +++ b/packages/vscode/src/DOCUMENTATION.md @@ -44,6 +44,8 @@ Keep `bridge.ts` as a thin orchestration layer that delegates message handling t The webview CSP permits `blob:` only for `worker-src` so shared UI parsers can run bounded local decompression off the main thread. Blob scripts remain disallowed by `script-src`. +The webview build emits each worker as one self-contained file. VS Code webviews cannot load module imports from inside a worker, so allowing worker URLs in the CSP is not enough when Rollup splits Shiki grammars into separate chunks. + - `bridge-localfs-proxy-runtime.ts` - Local `/api/fs/read` and `/api/fs/raw` proxy helpers and shared proxy utility helpers. - Workspace-contained Markdown gallery images use these local filesystem diff --git a/packages/vscode/src/viteConfig.test.ts b/packages/vscode/src/viteConfig.test.ts new file mode 100644 index 00000000..a4ef5d22 --- /dev/null +++ b/packages/vscode/src/viteConfig.test.ts @@ -0,0 +1,11 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { describe, test } from 'node:test'; + +const source = readFileSync(new URL('../vite.config.ts', import.meta.url), 'utf8'); + +describe('VS Code webview worker build', () => { + test('bundles worker imports into one file', () => { + assert.match(source, /worker:\s*\{[\s\S]*?inlineDynamicImports:\s*true/); + }); +}); diff --git a/packages/vscode/vite.config.ts b/packages/vscode/vite.config.ts index 80fc9693..3544061c 100644 --- a/packages/vscode/vite.config.ts +++ b/packages/vscode/vite.config.ts @@ -25,6 +25,13 @@ export default defineConfig(({ mode }) => ({ }, worker: { format: 'es', + // VS Code webviews cannot load module imports from inside a web worker. + // Keep the Shiki worker self-contained instead of emitting grammar chunks. + rollupOptions: { + output: { + inlineDynamicImports: true, + }, + }, }, define: { 'process.env.NODE_ENV': JSON.stringify(mode === 'production' ? 'production' : 'development'),