mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(emcn): keep Prism grammar registrations in bundle, never throw on missing grammar (#5293)
Consumers import { highlight, languages } from the @sim/emcn barrel, which
re-exported Prism's highlight straight from prismjs. Bundlers resolved that
passthrough directly from prismjs and skipped prism.ts's module body, dropping
the side-effect grammar registrations so languages.json (etc.) were undefined at
runtime. Prism then threw 'The language "json" has no grammar.', crashing the
start-block file[] input format field and every other workflow-editor code
highlighter.
Own highlight as a local wrapper so the registrations stay in the dependency
graph, and degrade to escaped plaintext when a grammar is missing instead of
throwing.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { highlight, languages } from 'prismjs'
|
||||
import { type Grammar, languages, highlight as prismHighlight } from 'prismjs'
|
||||
import 'prismjs/components/prism-javascript'
|
||||
import 'prismjs/components/prism-python'
|
||||
import 'prismjs/components/prism-json'
|
||||
@@ -10,10 +10,32 @@ import 'prismjs/components/prism-json'
|
||||
* shared `Prism.languages` registry), which marks any module that statically
|
||||
* imports them as having side effects and therefore non-tree-shakeable. Keeping
|
||||
* them here — rather than in `code.tsx` — ensures Prism only enters bundles that
|
||||
* actually import `highlight`/`languages`, instead of every consumer of the
|
||||
* shared `@sim/emcn` barrel (which re-exports `Code`).
|
||||
* actually import these utilities, instead of every consumer of the shared
|
||||
* `@sim/emcn` barrel (which re-exports `Code`).
|
||||
*
|
||||
* `code.tsx` itself never imports this module statically; it loads it lazily via
|
||||
* dynamic `import()` on first highlight.
|
||||
*
|
||||
* `highlight` is a local wrapper rather than a re-export of Prism's `highlight`.
|
||||
* A bare re-export lets bundlers resolve the binding straight from `prismjs` and
|
||||
* skip this module's body, dropping the grammar registrations above so
|
||||
* `languages.json` (etc.) become `undefined` at runtime. Owning the function
|
||||
* keeps the registrations in the dependency graph and lets us degrade to escaped
|
||||
* plaintext when a grammar is missing instead of throwing.
|
||||
*/
|
||||
|
||||
function escapeHtml(text: string): string {
|
||||
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights `code` with the given Prism `grammar`, returning HTML markup.
|
||||
* Falls back to escaped plaintext when `grammar` is undefined so a missing or
|
||||
* unregistered language never throws `The language "<x>" has no grammar.`.
|
||||
*/
|
||||
function highlight(code: string, grammar: Grammar | undefined, language: string): string {
|
||||
if (!grammar) return escapeHtml(code)
|
||||
return prismHighlight(code, grammar, language)
|
||||
}
|
||||
|
||||
export { highlight, languages }
|
||||
|
||||
Reference in New Issue
Block a user