-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
require() prefers ES Modules? #6321
Comments
Hi @tmcw. This is actually the way the Webpack 4 is handling modules, not us. If ES modules are supplied, they're preferred - which is great news, as it should cut down on bundle size. For you, as a maintainer or publisher, I get that it's confusing. Users, when using Let me know if you have any other questions, and sorry that this has caused you issues. |
Thanks for the detail. Well, that's a bummer. In my case, it looks like [someone's application] → depends on [module A i don't control] → depends on [my module B] So, module A specified a semver range for its dependency on B, and uses require(). So, when I publish a patch or minor update that adds an ES module entry point to module B, it breaks module A, and then breaks someone's applications. I know this isn't the void to be shouting into, but geez that's not a good system. Module A might not want to publish an ES Module entry point, or it might be abandoned or unmaintained - in this case, it is unmaintained. This puts additional strain on module authors and makes a backwards-compatible addition non-backwards-compatible only for webpack users. |
? tree-shaking works fine on commonjs modules too using https://github.com/indutny/common-shake |
Hi @tmcw, that's very interesting... I don't know, but I would assume that a dependency of a dependency shouldn't be handled that way - for the exact reason you've highlighted. Perhaps this is an issue to discuss with the Webpack team? Thanks @substack, I was talking about out-of-the-box webpack though. |
Hi there, I went digging to find a core webpack bug to report, but unfortunately I found my way back here. Here's a minimal testcase, based on an ejected create-react-app configuration: https://github.com/tmcw/create-react-app-6321 I've confirmed that this behavior doesn't happen with an zero-config Webpack 4 setup and is only triggered by create-react-apps's overeager (imho) transpilation of all app dependencies and sub-dependencies. |
Thanks @tmcw, this will obviously need more investigation then. Would you be interested in digging a little deeper and raising a PR? If not, I could try to get onto it over the weekend. |
@tmcw there's a webpack issue here webpack/webpack#5756 From 2017. @sokra said "won't fix" And there's another one from 2018 that's pretty much the same thing with the same response: webpack/webpack#6584 |
Using different Let's assume One package i. e. In this case This is bad for bundle size, in this reacts case it even breaks the app. In this case you would have to ensure to only use CJS or ESM packages. Probably resulting in only CJS, which will lead to complete banning of ESM, which would make everyone very sad. Yes, always preferring the My guideline for package authors: |
Ah, I hadn't considered the scenario where two packages import the same package differently. So it seems there's no two ways about it: package authors will one-by-one add a I wonder, where on the internet is the suggestion to add the non-standard |
To the extent that anything beyond what npm documents in package.json is 'standard', the 'module' field is a community standard and has de-facto documentation in a number of locations - a spec proposal, bundler docs, etc. Tobias's rationale makes sense, even though it's a little inconvenient for me 😉. But the issues that remain are that:
Edit: I'm happy to write up a PSA about "adding module is (probably) a major version change" |
I agree that this is a little messy right now (as an industry) and we need to keep working together to improve the situation. However, I feel that perhaps this is a good time to close this thread off unless anyone has any suggestions on what we can do to make this easier for future developers? |
Yep, besides spreading the knowledge I don't see any other tasks here. |
Is this a bug report?
Yes, I think this is a bug report.
Did you try recovering your dependencies?
Yes, and this bug doesn't have anything to do with installing dependencies.
Which terms did you search for in User Guide?
Environment
Steps to Reproduce
(Write your steps here:)
module
. This feels, to you, like a minor change: you're adding something.require()
. require(), for some reason, loads the ES Module now, not the CommonJS module, and in the unfortunate haphazard way that the two interop, it is now 'broken', and the require() returns an object with{default:fn()}
instead offn()
as it did before.Expected Behavior
I assumed that the CommonJS syntax require() would use the CommonJS entry point, and the ES Module import would use the ES Module entry point, and that this wouldn't be a breaking change.
Actual Behavior
The module appears to be 'broken' to people consuming it via create-react-app - and possibly all similar webpack-related toolchains.
As a module maintainer, this leaves me with no clear way to introduce ES Module entry points into my modules without breaking them for CommonJS users. And I can't see why this behavior - apparently preferring the
module
entry point to themain
one even throughrequire()
would be default.Reproducible Demo
One-commit demo is at https://github.com/tmcw/cra-example
The one commit is https://github.com/tmcw/cra-example/commit/c1262372fba3104f25d6dad3d77c37b0ad8a4442 which adds a dependency, uses it with
require()
and console.logs it.The text was updated successfully, but these errors were encountered: