-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't import CJS deep import #1438
Comments
It works. You'll need to provide a repro. |
@yyx990803 Not sure what repro to produce, those 3 lines are literally the entire module they're in. |
I already spent 10 minutes reproducing this and |
OK, while building the repro I noticed: it works when using the CLI but not when passing options to the JS API. You can clone this repro, it is vite If you run
Supported in Node 14.3+ and Chrome/Edge 89+. BTW is there a better way to import Prism without relying on |
As of e438802 the following should just work without any config: import Prism from 'prismjs'
import 'prismjs/components/prism-csharp'
export default Prism No need for top level await. |
Can you please explain to me what does Vite do to guarantee that it works? I thought Vite served files as native modules but the ESM specs (to the best of my knowledge) doesn't mandate an order of execution identical to source code imports. It only requires them to have all been initialized before the module is actually run. The problem with With ESM no dependency exist between these two modules, so |
I'm gonna add that I'm aware that both Webpack and Rollup offer ordering guarantee when possible (non-circular, etc.) inside a single chunk (no code-splitting, etc.). So this code is fine when bundled. Since Vite is serving file as unmodified ESM modules to browsers, I'm just curious how it works during dev. |
I tested in all major browsers and the de facto behavior is that they all respect import statement order in terms of evaluation. The modules are fetched in parallel, but the code evaluation are strictly performed in import order. The spec itself isn't super clear about this, but that is the behavior that all major browsers have decided to align with (which makes sense IMO, since there isn't major perf loss in this - parse and fetch can be performed without actually evaluating the module). The code works even if I artificially delay the response for the main |
That surprised me, so I did more research. I was wrong (but caveats apply, see below).
Quick aside: actually, there is perf to win here. You could execute modules that are already ready in parallel with parsing/fetching of slower/larger previous modules, hence completing earlier. First I did some tests (Win, Edge 89). // main.js
import './a'
import './b'
console.log("Main")
// a.js
console.log('A')
// b.js
console.log('B') Basic run is A -> B -> Main. Then I blocked script A using Fiddler. 10s later nothing happened. When I released the module in Fiddler everything ran A -> B -> Main, so clearly the browser was waiting for in-order execution. De facto standard is a dangerous thing is it may change based on heuristics, platforms, new releases... So I checked the EcmaScript specification and turns out in-order execution might actually be specified in there. In §15.2.1.16 it defines Then §15.2.1.16.5 ModuleEvaluation() Concrete Method says:
So that implies evaluation of imported modules happen in source order. ✔️ Of course, that's assuming modules A and B are independent, otherwise module A would trigger evaluation of module B itself, but that's really what you'd expect. Except I found a caveat where statically importing A, B is different from importing A then dynamically importing B. await new Promise(r => setTimeout(r, 5000))
console.log('A') And guess what? Module B evaluation started before A completed (of course Main waited for A to complete). Other than that, I suppose one can assume that independent, synchronous modules evaluate in order, which is nice for modules that have global effects, notably importing polyfills at the start of your program. |
This is similar to many deep import bugs, which are closed.
There's currently #1041 that is open, but it seems the cause there is linking.
This looks exactly like #1067, which was closed because its author was "lucky" having access to ESM sources.
Describe the bug
I'm trying to use
prismjs
and include thecsharp
language grammar.Here's my module:
Note that
prismjs
is entirely written in Common JS style (and even worse: uses global variables, hence theawait import()
).When I try to import this module, Vite says this on the console:
So I followed the instruction and added
optimizeDeps: { include: [ "prismjs/components/prism-csharp"] }
to my config, which changed nothing.I tried anything that came to mind, like adding
.js
to the path, tryingexclude: ["prismjs"]
, nothing worked.From the comments in #1067 I have the impression that you can't exclude this lib from pre-opt because it's written in CommonJS style.
That issue seem to be the same bug but it was closed without a fix (workaround was to load a ESM source instead... when available).
System Info
vite
version: 2.0.0-beta.12The text was updated successfully, but these errors were encountered: