-
-
Notifications
You must be signed in to change notification settings - Fork 600
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
[commonjs] Add defaultIsModuleExports
option to match Node.js behavior
#838
[commonjs] Add defaultIsModuleExports
option to match Node.js behavior
#838
Conversation
packages/commonjs/README.md
Outdated
@@ -174,6 +174,13 @@ If you set `esmExternals` to `true`, this plugins assumes that all external depe | |||
|
|||
You can also supply an array of ids to be treated as ES modules, or a function that will be passed each external id to determine if it is an ES module. | |||
|
|||
### `nodeDefaultImport` |
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 moving forward here!
I was thinking about the name of the option and I am not happy about this choice as it references an environment (Node) that may change while IMO it should rather reflect functionality. So what this is about is as I understand it is to skip the default import interop in favour of assuming the default is module.exports
. There are several ways to handle this (names are just suggestions):
moduleExportsIsDefault: true | false | "auto"
where "auto" is the current behaviour (could also be "detect")cjsDefaultExport: "module.exports" | "default" | "auto"
where "auto" is the current behaviour (orcjsDefaultImport
depending which way you view it)
Admittedly that the version where the default export is always exports.default
may not be as useful, but what do I know. Could be a micro-optimisation for some. Thoughts?
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.
Not sure we should change the default, but I keep twisting the idea of a config plugin in my head that would just configure commonjs, node-resolve and rollup for Node compatibility.
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 have a slight preference for the moduleExportsIsDefault: true | false | "auto"
(or defaultIsModuleExports
? since we are giving a value to the "default" binding) option, since typing "module.exports"
inside a string (thus often without autocompletion) can be a bit harder.
There are already precedents for boolean | string
options, such as requireReturnsDefault
.
Admittedly that the version where the default export is always exports.default may not be as useful, but what do I know. Could be a micro-optimisation for some. Thoughts?
We actually have an option in Babel exactly for that (https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#nointerop), even if we don't have data about how many people use it.
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.
But you do not have the false
case, i.e. always assuming the default export is module.exports.default
, right? That's the one where I am not sure people really would use it (and if we should even add it).
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.
noInterop: true
means "always get .default
, without first checking if it has __esModule
: https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop/import-default-only
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.
Ah I see. So reading babel/babel#12838 I understand now that you are also going for a three-state flag 👍
or defaultIsModuleExports
I would be fine with that as well.
b514add
to
27c5bdc
Compare
27c5bdc
to
fc73572
Compare
named: named | ||
}; | ||
|
||
export default input.default; |
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'm not sure about this one. Should we avoid injecting the default export when it's not present? But then, how do we handle cases where input.default
exists but it's not easily statically analyzable?
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 question. I would lean towards adding it always for now, though maybe as undefined
, as this is similar to the current behaviour.
nodeDefaultImport
option to match Node.js behaviordefaultIsModuleExports
option to match Node.js behavior
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 putting in the work!
Great work, thanks @nicolo-ribaudo for the PR. |
Thanks @lukastaegert and @guybedford for the reviews! |
We are releasing Babel 7.14.0 next week, and it contains an option which is almost the same as this one. Is it ok if we mention in the release post that the next version of |
@nicolo-ribaudo thanks for the heads up, I'll do my best to see if we can be release ready by the end of the week but can't guarantee it. |
…behavior (#838) * [commonjs] Add `nodeDefaultImport` option to match Node.js behavior * Undo unrelated changes * Undo editor autoformatter * Change option
@lukastaegert @nicolo-ribaudo is there not a way to get @rollup/plugin-babel to just output We still have a lot of external modules that are transpiled CJS with |
Okay nevermind, seems like I can get it to work by using
|
Can you try using |
@nicolo-ribaudo oh, many thanks! Sorry, I hadn't discovered that option. |
Rollup Plugin Name:
commonjs
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers: Fixes #635
Description
I was trying to modify Babel's sources (ref) to that they work:
I achieved (2) by authoring our sources according to what Node.js expects.
I achieved (1) using a small custom Babel plugin, and we'll make it an option (babel/babel#12838) of
@babel/plugin-transform-modules-commonjs
in the next minor version.I didn't realize (3) was not working, I now opened a PR with another custom Babel plugin (babel/babel#13017) which replaces
import foo
withimport * as foo
for the few CJS deps we have that use__esModule = true
.I think that this option should eventually default totrue
in the future, but we are probably not ready for it yet.