-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Feature Use Case
I'm a maintainer of the uuid npm module and I'm currently trying to add ESM support for node, see uuidjs/uuid#402.
Since the uuid module needs to store internal state I'm running into the dual package hazard and I want to prevent it using the "isolate state" approach.
In practice this means that I have the following line in the ESM source:
import state from './v1state.cjs';Unfortunately I can now no longer bundle code that depends on the uuid module unless I add the commonjs() plugin to treat *.cjs files as shown here https://github.com/uuidjs/uuid/pull/402/files#diff-ff6e5f22a9c7e66987b19c0199636480R16-R18
If I leave the commonjs plugin out I get
[!] Error: 'default' is not exported by ../../dist/esm-browser/v1state.cjs, imported by ../../dist/esm-browser/v1.js
Now I don't want to ship a library, that requires users of the library to set up extra rollup config but I also don't want to ship it exposing the dual package hazard.
This problem doesn't exist in webpack since webpack seems to have auto-detection of CommonJS files and supports parsing them out-of-the-box.
I understand that rollup explicitly is an "ES Module" bundler. However I can imagine that other library authors will want to ship dual CommonJS/ES Module packages and they will run into the same issue if they choose the "isolate state" approach.
The Node.js docs also mention the ESM-Wrapper approach, where you ship a CommonJS module and only add an ESM wrapper around it for use with Node.js. This would effectively allow me to ship a different true ESM build for bundling with rollup with the downside of Node.js still executing the CommonJS source. That's probably fine for a small library like uuid() but maybe something that bigger libraries would want to avoid.
It should be noted that, as far as I understand, bundles created with rollup are not affected by the dual package hazard. This is due to the fact that rollup will always resolve to the same (ES Module) source files as specified by the "module": property in package.json for the uuid module, irrespective of whether it is require()d as a transitive dependency inside a CommonJS module or imported in an ES Module.
So the issue here really is that, as far as I understand, library authors have to ship different code for direct execution as ES Module in Node.js and for consumption by rollup.
Feature Proposal
I am not sure what the proposal should be, I would mainly like to clarify with the rollup maintainers how you think about the dual package hazard and whether you think that library authors should ship different code for direct execution with Node.js and for bundler consumption.