-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
import-first loading of test files #4635
Conversation
@giltayar I have some questions:
Is this remark linked to eg. We should align our docs as well. |
According to the documentation, v12.17.0 (see image below for history of Node ESM)
All ESM functionality was backported to v12, and is stable from v12.22.0:
A few tests in the mocha suite actually caught me when I did a naive implementation, which was to just use
uncomprehensive error messages: We had a problem with showing syntax errors on ESM files imported, which is a v8 bug, which I worked around using a hackish solution. The bug in v8 is still there, as is the workaround. Fortunately (and I checked!), the problem does not exist when missing file extensions: see above. CJS loaders: if
This is done using CJS loaders aka "register hooks", and is not a problem (see above)
Yes. at my company we use an ESM loader I wrote that is the equivalent of
Not sure why: this should be completely transparent to the user. Note: I would completely understand if we wait with this PR a few months, for the next semver-major release, so that more ESM experience is out there, and ESM is used more. I have a hack at my company that rewrites |
It's a good idea to switch to import-first, but limiting our package engine to >=v12.22 (stable) seems too restricting to me. Otherwise waiting for Node-v12's end-of-life in 2022-04-30 isn't an option either.
Our docs still declares Node's native ESM support as experimental. |
I think you're right. It's a good idea. Will do that now in this PR.
I'll change the docs in this PR.
This will probably break some people (and will mean I need to fix some of the tests in the test suite). I think leaving the fallback is a good idea. But your call: I'm pretty indifferent.
Not sure I understood what you mean. |
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 think we don't need utils.supportsEsModules()
any longer, and Mocha.prototype.loadFilesAsync
could be simplified as well. IMO there is no need to check for browser, as shown by Mocha.prototype.loadFiles
.
FIrst try ESM, and only if that fails, load test file using require. This enables an ESM loader to have first dibs at transforming the file.
Also removed outdated information and references to the "esm" module that emulated ESM in Node.js
ed1f4a0
to
35a5c9f
Compare
@juergba I agree that the code needs refactoring to remove cruft. I actually started writing this PR that way, but found out that the removal of the cruft obscures the main point of this PR, which is doing the loading using ESM-first. I would gladly contribute another PR after this one to refactor the code once ESM and async are the main ways we load the test code. |
ok, I agree. I have to do some testing with Mocha's programmatic usage. What are the implications of this PR? |
We still need
So I guess this PR looks fine so far. |
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.
@giltayar I'm going to merge tonight.
@juergba |
@juergba yes, it is a big change, and we should be wary, but given that this will be in a semver-major release, hopefully we'll get early signs of a disaster before everybody gets the version, and we'll be able to revert (or quickly fix). Thank you for the trust. And for a HUGE load of tests that make me feel confident that it will be alright. |
@giltayar do you have any wishes regarding release notes? I imagine that many users could be confused with
Do you want this to be part of v9.0.0? |
Let me have a go at this: Mocha is going ESM-first! This means that it will first use
Since this is a refactor only, It could be part of a later release. It all depends when you want to release 9.0.0, as I will be able to do this PR only starting next week. |
I'm planning to publish v9.0.0 this weekend and will add your text to the release notes. I'm missing the info that |
@juergba you're right about import also importing CJS. Here's my change: Mocha is going ESM-first! This means that it will now use ESM |
@giltayar When we load a test file There is an experimental ts-node/esm loader which transpiles ESM/TS files, no problems with that one either? Edit: ts-node/esm seems to work as before if |
Not if there's a loader that loads |
@giltayar I'm not going to publish v9.0.0 today. I have struggled for hours with transpiling issues, |
This may be of little use for your needs, @juergba , but FWIW, I have found https://www.npmjs.com/package/babel-plugin-transform-async-to-promises to work well for my needs without adding its dependency. |
Just a heads-up that node will be making some breaking changes to the unstable ESM loaders API soon which may break users. |
Description of the Change
Test files can be either CJS or ESM. Up to now, we used the following method to support both: first require, and if that fails with
ERR_REQUIRE_ESM
, then use import.This was a necessity so long as some supported Node versions did not support ESM. Now that all supported versions of Node support ESM, we can go to a better import-first method, whereby we first try using
import(file)
and only if that fails, do we tryrequire
.This is a big change, which is theoretically transparent, but could result in unforeseen behavior. We should do this in a SEMVER_MAJOR change.
Alternate Designs
Figure out whether the file is CJS or ESM: unfortunately, the algorithm is complex and basically should replicate Node's, which is practically impossible.
Why should this be in core?
Because no plugin can do this.
Benefits
Allowing ESM loaders to transform a file.
Possible Drawbacks
Backward compatibility: are there any scenarios which we have not foreseen, that fail when we do import first? I couldn't think of any, but there could be. That is why this should be a SEMVER_MAJOR change.