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
Improve external and inter-chunk import execution order #2508
Conversation
2601256
to
df0caff
Compare
…g module order test
df0caff
to
dbbd52d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ausgezeichnet, das habe ich vorher übersehen.
src/utils/execution-order.ts
Outdated
|
||
export function analyzeModuleExecution( | ||
entryModules: Module[], | ||
generateChunkHashes: boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that these hashes are not the same as "chunk hashes" as chunk hashes should be content-based.
So we have two concept of chunk hash:
- The content-based hash of the inner chunk content with output options
- The graph colouring hash
I prefer to use chunkHash
to refer to (1) as it is what most users would naively expect I believe.
So either colouringHash
or graphHash
or similar for this would be a more useful name I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
} | ||
|
||
for (const dynamicModule of module.dynamicImportResolutions) { | ||
if (!(dynamicModule.resolution instanceof Module)) continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess dynamic imports to external modules are ok without an execIndex, although worth bearing this in mind from a data consistency point of view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Will change to make sure all (external and internal) modules are initialized consistently in case their execIndex
is never set.
BTW your German is impeccable, that is to say Dein Deutsch ist makellos 😂 |
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers:
Resolves #2490
Description
Previously, the order of external imports as well as the order of imports from other chunks was determined via this simple algorithm:
If there are no cycles, this satisfied the guarantee that a module was only executed once all its dependencies had been executed. If external modules had side-effects, it was not guaranteed, though, that these side-effects were executed in order. Consider this example:
Inside the chunk, the execution order is
other.js -> main.js
, so the old algorithm would generate the execution orderwhile the correct order is
This PR fixes this by
Beyond that, this also refactors and extracts some of the analysis code. For reviewing, the new logic is entirely contained in the commit "Sort external and inter-chunk imports according to execution order".
Also, for the first time, this PR adds functional tests with code-splitting! These tests are run via a special
require
function that knows all generated chunks and resolves accordingly. I plan on refining this logic within the 1.0 PR.Note that it is impossible to always maintain correct execution order, even via this PR, when bundling. This PR, however, gets us as close as possible. A trivial example where it is impossible to have correct execution order is this:
which has the execution order
external -> internal.js -> main
while the correct execution order would beinternal.js -> external -> main
. But this lies within the nature of bundling.