fix: fix error with <Prism /> component in Cloudflare Workers#15723
fix: fix error with <Prism /> component in Cloudflare Workers#15723rururux wants to merge 16 commits intowithastro:mainfrom
<Prism /> component in Cloudflare Workers#15723Conversation
🦋 Changeset detectedLatest commit: df376c0 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
packages/astro-prism/tsconfig.json
Outdated
| "rootDir": "./src", | ||
| "outDir": "./dist" | ||
| "outDir": "./dist", | ||
| "types": ["vite/client"] |
There was a problem hiding this comment.
This line is required to load the type definitions for import.meta.glob().
|
🤔 |
This comment was marked as outdated.
This comment was marked as outdated.
|
@rururux if the code that we're attempting to load is CJS, we should use |
|
Thank you for the suggestion! I tried the approach you proposed, and while it does improve stability, 20:07:54 [WARN] [vite] Failed to resolve dependency: @astrojs/prism > prismjs, present in ssr 'optimizeDeps.include'
20:07:54 [WARN] [vite] Failed to resolve dependency: @astrojs/prism > prismjs/components.js, present in ssr 'optimizeDeps.include'
20:07:54 [WARN] [vite] Failed to resolve dependency: @astrojs/prism > prismjs/dependencies.js, present in ssr 'optimizeDeps.include' |
|
Also, I just noticed there's actually an issue with the implementation in this PR, edit: done |
|
I added a simple detection logic to the Cloudflare Workers integration's Vite plugin that checks whether One limitation to note: since the check works by reading the If you'd prefer, I can update the Cloudflare integration's test fixtures to install |
ematipico
left a comment
There was a problem hiding this comment.
I need to wrap my head with the new code. There are weird things
| return; | ||
| } | ||
|
|
||
| const pathToLanguage = `../node_modules/prismjs/components/prism-${lang}.js`; |
There was a problem hiding this comment.
Can you explain me why we're doing this? This feels very hacky and crawling node_modules could lead to all sorts of things
There was a problem hiding this comment.
The reason I'm referencing node_modules directly to load language files is that using import.meta.glob for dynamic package imports causes an error when specifying something like import.meta.glob('prismjs/components/prism-*.js'): Internal server error: Invalid glob: "prismjs/components/prism-*.js" (resolved: "prismjs/components/prism-*.js"). It must start with '/' or './'
Using await import(`prismjs/components/prism-${lang}.js`) also fails with a The above dynamic import cannot be analyzed by Vite. warning.
https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
So i went with the approach of referencing node_modules directly.
I do have one alternative approach in mind that might work, and i'm going to give it a try now.
There was a problem hiding this comment.
One of the approaches i had in mind doesn't seem to work out.
The tricky part is that the path needs to be statically known at the time of the dynamic import, so the options to work around this would be either pre-writing all language file paths to some file, or passing the paths through a virtual module from the Cloudflare Workers integration plugin.
|
I've switched to an approach that uses a virtual module to load Prism language files, but only in the Cloudflare Workers environment. |
fixes: #15722
Changes
loadLanguagesfrom prismjs, rewrote them as ESM, and configured them to be loaded in Cloudflare Workers environments.runHighlighterWithAstrofunction to an async function.runHighlighterWithAstroto also handle it as an async function.Fixes a CommonJS-related error that occurred when using the Cloudflare Workers integration with the
<Prism />component in the latest beta of Astro.The root cause was that the
loadLanguagesfunction exported from prismjs usedrequire()andrequire.resolve()internally.To work around this, i ported
loadLanguagesand its dependencies from the prismjs repository, rewrote them as ESM, and configured them to be loaded only in Cloudflare Workers environments.Initially, i considered simply adding
'prismjs/components/index.js'tooptimizeDeps.includein@astrojs/cloudflare, but this approach was abandoned because whilerequire()was replaced,require.resolve()remained as-is and still caused an error.As mentioned in this comment, I encountered an interesting phenomenon while investigating this issue.Specifically, statically importing the
prismjsmodule in the workerd environment caused the tests to become flaky, while switching to dynamic import made them stable.This pull request therefore takes that approach. I've left an explanatory comment in the workerd-specific file.
Reference
loadLanguages: https://github.com/PrismJS/prism/blob/76dde18a575831c91491895193f56081ac08b0c5/components/index.jsTesting
Added a test to verify that the component works without errors in a workerd environment.
Docs
N/A, bug fix