-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
module: error for CJS .js load within type: module #29492
Conversation
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.
LGTM. Note: This does technically introduce a subtle change in the main
resolution: If the package.json
gets created after the initial attempt, this will now be hidden by the cache. Previously it wasn't caching the "no package.json
" case for main
.
Example:
- Try to load
foo
which doesn't exist. - Create
node_modules/foo
. - Retry loading
foo
.
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.
Also: Does the esm
loader currently read a index.js
before a index.mjs
(if both are present) when type: module
is unset and import the index.js
as cjs? That's also needed.
lib/internal/modules/cjs/loader.js
Outdated
@@ -943,6 +946,10 @@ Module.prototype._compile = function(content, filename) { | |||
|
|||
// Native extension for .js | |||
Module._extensions['.js'] = function(module, filename) { | |||
const pkg = readPackageScope(filename); | |||
if (pkg && pkg.type === 'module') { | |||
throw new ERR_REQUIRE_ESM(filename); |
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.
Should this error be behind the flag for now, or are we OK with throwing here without the --experimental-modules
flag set?
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.
Just like we don't check the flag for loading from .mjs
, it seems important to include unflagged as soon as possible to ensure we are reserving the compatibility space, unless you feel strongly about this?
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 want this unflagged or at the very least using a different flag. This is cleaning up an inconsistency with how .mjs
and .js
are handled so if throwing on .mjs
isn't behind a flag, neither should this imo (and vice versa if I misremembered the current state :)).
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.
it seems important to include unflagged as soon as possible to ensure we are reserving the compatibility space, unless you feel strongly about this?
Nah, I'm fine with it (hence the approve), just wanted to ask if it had been considered.
Multiple failures in CI for Example: 08:32:30 not ok 1491 parallel/test-policy-parse-integrity
08:32:30 ---
08:32:30 duration_ms: 0.173
08:32:30 severity: fail
08:32:30 exitcode: 1
08:32:30 stack: |-
08:32:30 assert.js:89
08:32:30 throw new AssertionError(obj);
08:32:30 ^
08:32:30
08:32:30 AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
08:32:30
08:32:30 1 !== 0
08:32:30
08:32:30 at test (/home/iojs/build/workspace/node-test-commit-linux/nodes/ubuntu1804-64/test/parallel/test-policy-parse-integrity.js:64:12)
08:32:30 at Object.<anonymous> (/home/iojs/build/workspace/node-test-commit-linux/nodes/ubuntu1804-64/test/parallel/test-policy-parse-integrity.js:68:1)
08:32:30 at Module._compile (internal/modules/cjs/loader.js:939:30)
08:32:30 at Object.Module._extensions..js (internal/modules/cjs/loader.js:954:10)
08:32:30 at Module.load (internal/modules/cjs/loader.js:792:32)
08:32:30 at Function.Module._load (internal/modules/cjs/loader.js:705:12)
08:32:30 at Function.Module.runMain (internal/modules/cjs/loader.js:1006:10)
08:32:30 at internal/main/run_main_module.js:17:11 {
08:32:30 generatedMessage: true,
08:32:30 code: 'ERR_ASSERTION',
08:32:30 actual: 1,
08:32:30 expected: 0,
08:32:30 operator: 'strictEqual'
08:32:30 }
08:32:30 ... |
@bmeck ^^^^^^ |
|
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 seems to not handle certain types of package.json
{"type": "module"}
won't fire this change. I assume this package.json above should still fire this error.
nit: additionally should this be fired for extension-less files and/or any files not picked up by ESM mappings to types?
@bmeck the test here is exactly for a Good questions re other extensions. ESM doesn't permit unknown extensions (as in it will throw), so there is no longer an ambiguity for those cases as it is clear they can only be loaded as CommonJS. This PR was specifically about handling the .js dual mode ambiguity between CJS and ESM. If you feel strongly that they should throw for unknown extensions in "type": "module" for CJS we can consider that further certainly. |
@guybedford I did: |
Ah, the JSON property filter needed an entry to handle a package.json without |
(This is still likely unrelated to CI failure though unfortunately) |
Finally tracked down the issue here, and it was an obvious problem with the policy test after all. Still not sure why it was flaky though as it was a package.json integrity check availability issue. |
As noted in multiple issues, this change creates a lot of incompatibilities. In a The only workaround so far is renaming the files to Please, move cjs type check behind experimental-modules flag or lift this check for |
It also sounds like other tools may have introduced incompatible assumptions about the |
I think it's less about that, and moreso that @NemoStein already adopted The name of the field is irrelevant - given the same order of events, the same thing could have happened with any name - all that could have avoided his breakage would have been only revealing the field name as the errors related to its' use were added. In a way, this is similar to the concerns tc39 had with |
I wasn't necessarily talk about the one comment, more about the overall situation. One of them is:
This project will not work after unflagging. It will still register babel, it will still "fail" to meet node's current assumption about |
Any tool that hooks into CommonJS internals, especially something using Since |
@weswigham One downside of removing the error on CommonJS |
The error is still here, it's just being moved to behind the |
On the other hand, since |
Also, If this change concerns you with it's breakiness, then you're concerned with not shipping |
@weswigham Sorry I think I was unclear. I meant if when we unflag, if this error isn’t present, then later adding I think we should either ship with this error when we unflag, and it’ll be painful for tools for awhile; or we at least ship with a deprecation warning so that we can ship |
I don't think the behavior of |
I'm not referring to current opt-in behavior. I'm referring to someday adding require of ESM and having that not be a breaking change. Once type module is unflagged, I want us to be able to still add require of ESM after that point. |
Even without require of esm it'd be a breaking change, if that's your perspective, as it'd go from being interpreted as cjs to being an error. |
That's why when we unflag I want to either keep the error or make it a deprecation warning. Then we can add require of ESM in Node 14 and it either wouldn't be considered a breaking change (as something going from an error to working is generally allowed as non-breaking) or it would be an allowed breaking change if it went from a deprecation warning to working differently. |
Literally does not matter then (you can do anything with a major version bump) does it? What matters is what we can unflag with. |
I suppose; but if we don't warn the community to update their code, we'll have this same issue in Node 14 where tools are "broken" by the change. If they get months or years of warnings first, they might be updated before 14 is released. |
This adds the CJS error that a
.js
file within type: module package scopes cannot be loaded from CJS.This was a resolution made at the last Node.js modules meeting (see notes).
The error thrown is the same one thrown for loading
.mjs
files from CJS.//cc @nodejs/modules-active-members