Skip to content

Commit 1718162

Browse files
ematipicorururux
andcommitted
Use better soluition for workerd engine
Co-authored-by: rururux <rururux@users.noreply.github.com>
1 parent e6b9610 commit 1718162

5 files changed

Lines changed: 29 additions & 19 deletions

File tree

packages/astro/components/Code.astro

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ import type { HTMLAttributes } from '../types.js';
1010
// Code.astro always uses Shiki, so import the virtual CSS module
1111
import 'virtual:astro:shiki-styles.css';
1212
13-
// Import JavaScript engine for Cloudflare Workers
14-
// Workers can't load WASM files from filesystem, so use JS engine instead
15-
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
1613
1714
interface Props extends Omit<HTMLAttributes<'pre'>, 'lang'> {
1815
/** The code to highlight. Required. */
@@ -112,14 +109,6 @@ if (typeof lang === 'object') {
112109
}
113110
}
114111
115-
// Detect Cloudflare Workers environment
116-
// Workers can't load WASM files from filesystem, so use JavaScript RegExp engine
117-
// Check for Cloudflare context that's injected by @astrojs/cloudflare adapter
118-
const isCloudflareWorkers =
119-
('cf' in Astro.request) || // Cloudflare request object
120-
('cfContext' in Astro.locals) || // Cloudflare context in locals
121-
('cloudflare' in Astro.locals); // Alternative location
122-
123112
const highlighter = await createShikiHighlighter({
124113
langs: [
125114
typeof lang === 'string'
@@ -131,7 +120,6 @@ const highlighter = await createShikiHighlighter({
131120
],
132121
theme,
133122
themes,
134-
...(isCloudflareWorkers ? { engine: createJavaScriptRegexEngine() } : {}),
135123
});
136124
137125
// Combine style-to-class transformer with user-provided transformers

packages/markdown/remark/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"main": "./dist/index.js",
1515
"exports": {
1616
".": "./dist/index.js",
17+
"./shiki/engine": "./dist/engine.js",
1718
"./shiki": "./dist/shiki.js",
1819
"./shiki-style-collector": "./dist/shiki-style-collector.js",
1920
"./transformers/style-to-class": "./dist/transformers/style-to-class.js"
@@ -22,6 +23,10 @@
2223
"#import-plugin": {
2324
"browser": "./dist/import-plugin-browser.js",
2425
"default": "./dist/import-plugin-default.js"
26+
},
27+
"#shiki-engine": {
28+
"workerd": "./dist/shiki-engine-workerd.js",
29+
"default": "./dist/shiki-engine-default.js"
2530
}
2631
},
2732
"files": [
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// shiki-engine-default.ts
2+
import type { RegexEngine } from 'shiki';
3+
import { createOnigurumaEngine } from 'shiki/engine/oniguruma';
4+
5+
export function loadShikiEngine(): Promise<RegexEngine> {
6+
return createOnigurumaEngine(import('shiki/wasm'));
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// shiki-engine-worker.ts
2+
import type { RegexEngine } from 'shiki';
3+
import { createOnigurumaEngine } from 'shiki/engine/oniguruma';
4+
5+
export function loadShikiEngine(): Promise<RegexEngine> {
6+
// @ts-ignore wasm type
7+
return createOnigurumaEngine(import('shiki/onig.wasm'));
8+
}

packages/markdown/remark/src/shiki.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import {
88
type HighlighterGeneric,
99
isSpecialLang,
1010
type LanguageRegistration,
11+
type RegexEngine,
1112
type ShikiTransformer,
1213
type ThemeRegistration,
1314
type ThemeRegistrationRaw,
1415
} from 'shiki';
1516
import { globalShikiStyleCollector } from './shiki-style-collector.js';
1617
import { transformerStyleToClass } from './transformers/style-to-class.js';
1718
import type { ThemePresets } from './types.js';
19+
import { loadShikiEngine } from '#shiki-engine';
1820

1921
export interface ShikiHighlighter {
2022
codeToHast(
@@ -34,11 +36,6 @@ export interface CreateShikiHighlighterOptions {
3436
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
3537
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
3638
langAlias?: HighlighterCoreOptions['langAlias'];
37-
/**
38-
* Custom regex engine for Shiki.
39-
* Use JavaScript engine for environments that can't load WASM files (e.g. Cloudflare Workers).
40-
*/
41-
engine?: HighlighterCoreOptions['engine'];
4239
}
4340

4441
export interface ShikiHighlighterHighlightOptions {
@@ -81,20 +78,25 @@ const cssVariablesTheme = () =>
8178
// Caches Promise<ShikiHighlighter> for reuse when the same theme and langs are provided
8279
const cachedHighlighters = new Map();
8380

81+
let shikiEngine: RegexEngine | undefined = undefined;
82+
8483
export async function createShikiHighlighter({
8584
langs = [],
8685
theme = 'github-dark',
8786
themes = {},
8887
langAlias = {},
89-
engine,
9088
}: CreateShikiHighlighterOptions = {}): Promise<ShikiHighlighter> {
9189
theme = theme === 'css-variables' ? cssVariablesTheme() : theme;
9290

91+
if (shikiEngine === undefined) {
92+
shikiEngine = await loadShikiEngine();
93+
}
94+
9395
const highlighterOptions = {
9496
langs: ['plaintext', ...langs],
9597
langAlias,
9698
themes: Object.values(themes).length ? Object.values(themes) : [theme],
97-
...(engine ? { engine } : {}),
99+
engine: shikiEngine,
98100
};
99101

100102
const key = JSON.stringify(highlighterOptions, Object.keys(highlighterOptions).sort());

0 commit comments

Comments
 (0)