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
Preserve import order for ESM #15031
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for jestjs ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
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.
Huh, I didn't know Node did that 😅
This should be behind a flag, yes 👍 It also needs integration tests
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.
oops, wrong button 😅
(also changelog entry)
@SimenB Thanks for the response, it turns out this is a bit more nuanced than I thought - though the cause and the solution I believe are the same, I was only able to repro this by mixing ESM and CJS. I ended up using almost the exact repro that my project had (albeit simpler) I'm confident there are other situations it would appear in too. It ended up being more complicated than I thought to add the |
181caf6
to
f079261
Compare
a248dc8
to
d70ff0d
Compare
@SimenB tests passing and changelog provided - it was fairly cumbersome adding the new option (the same change required in lots of files) please let me know if I got it wrong |
Yeah I was caught out by that in #15016 - I do wonder if it might be worth trying to colocate some of the changes or have a template-ish doc outlining the different places that should be changed. fwiwi it looks like you've just missed updating |
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.
thanks for adding tests!
Could you update the docs as well? Add the new option to https://jestjs.io/docs/configuration
@SimenB tests actually passing now 🤣 and I believe I updated the documentation too (though wasn't sure exactly which file relates to the website) |
@SimenB don't review this yet - just found that when you have circular dependencies jest now hangs because of this change - looking into it |
Summary
Ensure Jest behaves the same was as Node when loading ESM modules - by linking and evaluating up the import tree - rather than fully linking and evaluating asynchronously.
I'm aware this is likely a divisive, opinionated change - I'd be totally fine with this behaviour being hidden behind a flag. If this has already been suggested and rejected - I apologies, I did look for similar issues/PRs but found none.
In many projects (including some of those I'm involved with) the code depends on load order, which undeniably it shouldn't. However it isn't always trivial to clean up these implicit depenencies - particularly where globals are involved, defined in third party packages. When running this project in node, imports are fully evaluated before their siblings are loaded - unless top level
await
is used.However, when running jest - imports are linked and evaluated in parallel - while this is completely correct ESM behaviour, it massively differs from node's behaviour, making jest hard to use in many large, legacy projects with complex dependency trees (any of which may fall victim to this).
A potential repro would be:
In node, this will output
Hello
- in jest, it will outputundefined
- because file2 evaluates before file1 does. Note - I've not tested this case specifically, where I observed it was more complex - but the concept is the same.Test plan
I've tested this on a complex project - if necessary I can throw together a repro. Without this change, jest will log
undefined
with the change it will logHello