-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[v3.0] Improve interop defaults #4611
Conversation
Thank you for your contribution! ❤️You can try out this pull request locally by installing Rollup via npm install rollup/rollup#improve-interop or load it into the REPL: |
Codecov Report
@@ Coverage Diff @@
## release-3.0.0 #4611 +/- ##
==============================================
Coverage 98.97% 98.98%
==============================================
Files 211 211
Lines 7428 7451 +23
Branches 2101 2104 +3
==============================================
+ Hits 7352 7375 +23
Misses 23 23
Partials 53 53
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
dbda147
to
df5317b
Compare
df5317b
to
96af403
Compare
Great to see this work, thanks for putting thought to these important defaults for Rollup module output to be as compatible as possible within the ecosystem.
Excellent! Then we just need Babel to do this as well now! //cc @nicolo-ribaudo For Finally it's now worth also keeping an eye on compat with cjs-module-lexer at this point, to avoid possible named exports regressions against Node.js. A simple approach might be to include a test that runs cjs-module-lexer on Rollup output so that future changes don't break named exports detection by mistake. |
No, it also applies to |
PR welcome! But I do not think it is critical for Rollup 3 as neither Rollup 3 nor this PR change how exports themselves are written, they only change import interop and the question whether to add the |
Agreed, if there is no output change it is unrelated to this PR, but worth bearing in mind for future changes and not forgetting about while on this topic! |
* Dummy commit * Change default for output.interop to "default", deprecate boolean and add "compat" * Add esModule: 'if-default-prop' and make it the default value * Statically resolve Symbol.toStringTag
This PR has been released as part of rollup@3.0.0-5. Note that this is a pre-release, so to test it, you need to install Rollup via |
* Dummy commit * Change default for output.interop to "default", deprecate boolean and add "compat" * Add esModule: 'if-default-prop' and make it the default value * Statically resolve Symbol.toStringTag
This PR has been released as part of rollup@3.0.0-6. Note that this is a pre-release, so to test it, you need to install Rollup via |
* Dummy commit * Change default for output.interop to "default", deprecate boolean and add "compat" * Add esModule: 'if-default-prop' and make it the default value * Statically resolve Symbol.toStringTag
This PR has been released as part of rollup@3.0.0-7. Note that this is a pre-release, so to test it, you need to install Rollup via |
This PR has been released as part of rollup@3.0.0-8. Note that this is a pre-release, so to test it, you need to install Rollup via |
* Dummy commit * Change default for output.interop to "default", deprecate boolean and add "compat" * Add esModule: 'if-default-prop' and make it the default value * Statically resolve Symbol.toStringTag
This PR has been released as part of rollup@3.0.0. You can test it via |
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers:
Description
The goal of this PR is to improve the defaults of the swamp that is "interop", i.e. how ESM input behaves when converted to and thrown into a CJS setting.
In Rollup, this is controlled by three options:
output.interop
: How to find the default import and handle namespace imports of external dependenciesoutput.exports
: What to do with default exports in your entry pointsoutput.esModule
: Whether to add the "__esModule" special property as a hint when generating non-ESM outputThe overall goal is to change the defaults so that Node’s interop behaviour is more or less the default behaviour. In Node
module.exports
module.exports
(if Node detects them. But I think it should be fine if Rollup handles all named exports, otherwise we would need to replicate the exact detection algorithm of NodeJS, which I would want to avoid)__esModule
is a regular export and not added by defaultnamespace[Symbol.toStringTag] === 'Module'
This means I want to implement the following:
output.interop
is"default"
output.interop
valuestrue
andfalse
are deprecated. However, I think the "duck-typing" interop oftrue
is still very useful (i.e. for the default export, we check if there is adefault
property onmodule.exports
first and return that, otherwise we returnmodule.exports
) because it works very well across tools with the only downside that it does not support "default" as a regular property onmodule.exports
. Therefore, it will make a return with a new name, probably "compat".output.exports
will remain as it is and default to"auto"
, which corresponds well to Node's interop wheremodule.exports
is the default import.output.esModule
will receive a new value "if-default-prop" which will become the new default and only add the flag if there is a default export and it is actually a property "default" onmodule.exports
. This situation cannot be mapped to CommonJS in a way that would work with Node interop anyway and users already receive a warning. This should reduce the proliferation of__esModule
properties in libraries.module.exports
, we additionally setmodule.exports[Symbol.toStringTag]
to"Module"
to promote this interop mechanism (if Symbols are permitted)Symbol.toStringTag
are handled so that they can be resolved staticallySymbol.toStringTag
is added/handled for external namespaces. Check what Node does for namespace imports from CJScc @guybedford who may have an opinion on this (and of course everyone else is invited to give feedback as well).