Skip to content

Global variable is initialized too late when lazy loading Lexical/Prism #21948

Description

@JamesHyot

Describe the regression

I'm experiencing this error in my app when using rolldown-vite instead of vite : Uncaught ReferenceError: Prism is not defined. Prism is supposed to be declared as a global variable whenever it gets imported by @lexical/code, and then lexical just calls Prism and an error is thrown. This used to work without issue with vite, either in dev mode or in production.

In my quest to provide a minimal reproduction, I've had a hard time reproducing it in production mode. I've noticed that the issue only happens when :

  • there's some lazy loading involved (in my app we're using Tanstack Router, in the repro I'm just using React.lazy)
  • the file making the import for @lexical/code needs to have its own js file produced during build time, which I provoke by importing it from two different "routes"
  • between the "working" code and the "broken" code, the call order changes

This is an example of a "working" code, where the previously defined Zo function that defines Prism globally is called prior to having Prism being accessed by "Prism.languages.clike = {"

Image

In the provided reproduction URL, the same part of the library is missing the call to Zo()

Image

the call to Zo() is made later in the file.

I've stumbled upon this issue vitejs#182 which seems to be close to what's happening here, and it turns out that using the experimental strictExecutionOrder: true solves the issue (in the Stackblitz, running npm install && npm run build && npm run preview works).
I'm not particularly sure how stable this fix is/how stable it will remain, but currently it solves part of the issue.

The problem is that the error still happens in dev mode, and I don't know how to fix it.

Your analysis will probably be better than mine but to reproduce in dev mode I need to :

  • lazy load two "routes"
  • both routes need to be referencing Prism with two different ways
    • route 1 imports from '@lexical/code'
    • route 2 imports from '@lexical/markdown'
    • this makes sure that a LexicalCode.dev-xxxxx.js file is created, with a require_prism method that is defined but called after "Prism.languages.clike = {" which throws the error

Reproduction

https://stackblitz.com/edit/vitejs-rolldown-vite-acq55ckk?file=src%2Fmain.tsx

Expected Behavior

With vite 7.1.4, the vite starter page shows up

Actual Behavior

The vite starter page appear briefly and when the library gets loaded lazily, the page turns blank with this error in the console : Uncaught ReferenceError: Prism is not defined.

Steps to Reproduce

npm install && npm run dev in the provided repro URL produces a blank page with a console error.

npm install && npm run build && npm run preview works as long as I have strictExecutionOrder: true in my vite.config.ts

System Info

System:
    OS: Windows 11 10.0.22621
    CPU: (16) x64 12th Gen Intel(R) Core(TM) i7-1260P
    Memory: 3.52 GB / 31.69 GB
  Binaries:
    Node: 22.14.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.2 - C:\Program Files\nodejs\npm.CMD
    pnpm: 10.6.5 - C:\Program Files\nodejs\pnpm.CMD
  Browsers:
    Edge: Chromium (139.0.3405.125)
    Internet Explorer: 11.0.22621.3527

Used Package Manager

npm

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug: upstreamBug in a dependency of Vitep2-edge-caseBug, but has workaround or limited in scope (priority)

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions