-
-
Notifications
You must be signed in to change notification settings - Fork 536
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
Implement ERR_REQUIRE_ESM when a file is require()
d which should be loaded as ESM
#1031
Conversation
This is technically a breaking change. Where previously we would attempt to execute I can implement this change conditionally for now, so it's only turned on if our ESM loader is used. Node 12's behavior is weirder than I thought depending on the minor version. Based on the behavior, I think checking node 12.15 node 12.16 throws an |
…ce it is a breaking change
const err = new Error(getMessage(filename, parentPath, packageJsonPath)) | ||
err.name = `Error [${ code }]` | ||
err.stack | ||
Object.defineProperty(err, 'name', { |
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.
This is pretty funky, might want to add a comment on why you do this since the first look makes it seem this line would erase err.name =
above.
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.
Done
dist-raw/node-cjs-loader-utils.js
Outdated
@@ -0,0 +1,118 @@ | |||
// copied from https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js |
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.
Is this whole file copied or which parts should be reviewed? Curious on things like we read JSON ourselves instead of relying on the require
cache.
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, this is actually coming from several files in node's source. I added comments to each item in this file with a permalink to the span of node's source code on github.
Thanks for the review. I added comments explaining what's going on in Re using the Would you prefer I tweak that code to use |
f3e3f18
to
6b15230
Compare
Codecov Report
@@ Coverage Diff @@
## master #1031 +/- ##
==========================================
+ Coverage 73.57% 73.68% +0.11%
==========================================
Files 4 6 +2
Lines 507 608 +101
Branches 130 142 +12
==========================================
+ Hits 373 448 +75
- Misses 83 101 +18
- Partials 51 59 +8
Continue to review full report at Codecov.
|
Node's built-in
require.extensions['.js']
will detect if a file should be loaded as ESM instead of CommonJS, according to the file's associatedpackage.json
. If it should be loaded as ESM, node throws an error. This change makes ourrequire.extensions
throw the same error.Mocha, for example, is relying on this error to detect when files are ESM and when they're CommonJS.
https://github.com/mochajs/mocha/blob/master/lib/esm-utils.js#L10-L22
This change detects when we're on a version of node that supports ESM, so it knows if it needs to (possibly) throw this error. If so, it runs the same code as node to find the relevant
package.json
and see if the file should be treated as ESM. If so, it throws an error that matches node's built-in error. I did this by copy-pasting the relevant bits of node's source code.Things I don't really love about this:
require()
the.js
file and see if we get the error. (slower but is proper "feature detection")Looking at how a few node versions behave:
node 12 always parses
import()
syntax, doesn't support native ESM without the--experimental-modules
, but always throws the error if you try torequire()
a file that should be loaded as ESM.node 10 & 11 always parses
import()
syntax, only loads ESM with--experimental-modules
, and never honors thepackage.json
"type"
field.