Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 36.4k
[25.x] module: fix extensionless CJS files in type:module packages#62083
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1952,12 +1952,12 @@ Module._extensions['.js'] = function(module, filename) { | ||||||||
| format = 'typescript'; | ||||||||
| } | ||||||||
| } else if (path.extname(filename) === '') { | ||||||||
| // Extensionless files skip the .js suffix check above. When type is explicit, | ||||||||
| // follow it so ESM syntax surfaces as SyntaxError for commonjs instead of | ||||||||
| // silently delegating to ESM. | ||||||||
| // Extensionless files skip the .js suffix check above. When type is commonjs, follow it so ESM | ||||||||
| // syntax surfaces as SyntaxError. For type: module, leave format undefined so our syntax | ||||||||
| // detection handles it (allowing CJS extensionless files in ESM packages). | ||||||||
Comment on lines
+1956
to
+1957
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does our syntax detection handle it? I think to confirm that it does, this PR also needs a test that requiring an extensionless file with ESM syntax in a This is also the part that worries me, though: according to our docs, syntax detection happens for
Assuming the comment here does what it claims to do, then this PR is creating a new exception to our docs: syntax detection applies in the above case, and for the string input, and for extensionless files in a Alternatively if this comment is just wrong and there's no syntax detection involved here, then we should fix this comment (and the PR description).
| ||||||||
| constwarning=`Module type of ${url} is not specified and it doesn't parse as CommonJS.\n`+ | |
| 'Reparsing as ES module because module syntax was detected. This incurs a performance overhead.\n'+ | |
| `To eliminate this warning, add "type": "module" to ${pjsonPath}.`; |
So I'm not sure what exception you're referring to? Are the docs and this warning all wrong and we've been secretly doing syntax detection for extensionless files in type: module scopes prior to #61600?
joyeecheungMar 10, 2026 •
edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
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.
Are the docs and this warning all wrong and we've been secretly doing syntax detection for extensionless files in type: module scopes prior to #61600?
Yes, or more precisely, we had been ignoring the type field for required extensionless files before 61600 - and still do on v20-v24. We didn't even read the package.json's type field at all for required extensionless files until 61600. That's why I say reverting it is going to make it more wrong.
As it turned out, if the type field is module, treating the required extensionless file as ESM caused a regression from the documented exception, so we have two choices to fix it for 25.
- If the type field is module, treat the required file as commonjs (this sounds even weirder, but it's what the doc says, and what yargs 17 expects). Note that this could still be breaking because it then disallows required extensionless ESM even with type: module, which has been available on v20-24.
- If type field is module, ignore the type field (what this PR does), so required extensionless files under this package.json can be either commonjs (what yargs 17 needs) or ESM (less weird for other cases, and what actually respecting the type field would've allowed), which is also the behavior we have for v20-v24.
Note that this is unrelated to entry points, and only for required extensionless files.
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.
These exceptions are nonsensical. I don't think the solution is to update our docs to correspond with these buggy code paths. We should just fix the code.
If a type field is set, no syntax detection should happen, period. No exceptions around extensionless files or require vs import vs entry point.
joyeecheungMar 11, 2026 •
edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
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 now feels like talking in circles...
I don't think the solution is to update our docs to correspond with these buggy code paths
I don't think anyone is proposing that. The proposal is to just remove the exception in docs in 26, which is being done in #62176
If a type field is set, no syntax detection should happen, period. No exceptions around extensionless files or require vs import vs entry point.
I think that was agreed all along, and it was what 61600 implemented, and we already tried to ship it in 25, and it turned out there was this regression, and that's how we realized there was a documented, conflicting exception elsewhere. So for 25 the exception for type: module + extensionless commonjs needs to remain in the docs with the code aligned back due to the regression - which was done in this PR. We are still removing other undocumented exceptions (notice how this PR still leaves type: commonjs properly respected, which was added in 61600, since there isn't a documented exception for it). But we will keep 61600 for 26 to disallow exceptions.
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.
Would it be possible to have extensionless files entirely ignore the package.json "type"? That seems like a more pragmatic approach given that they are designed to exist outside of package boundaries in most "binary execution" use cases.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| module.exports = { hello: 'world' }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "type": "module" | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
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.