npm-esm-vs-cjs icon indicating copy to clipboard operation
npm-esm-vs-cjs copied to clipboard

Some modules labeled 'esm' are dual

Open joyeecheung opened this issue 1 year ago • 2 comments

First of all, thanks for doing this project, it's very helpful for looking into the ESM situation in the ecosystem!

I am using the data in data/2024-02-20.json to find high impact packages that are ESM-only in order to test my require(esm) implementation & check the performance. Along the way I noticed that some packages labeled esm seem to be actually dual (at least, the can be both required and imported). So far the packages like this that I've found are:

  • tslib
  • fs-extra
  • axios
  • parse5
  • node-releases (this is just a bunch of .json files so can be required or imported with import attributes)
  • ts-node
  • @eslint-community/regexpp
  • babel-plugin-polyfill-regenerator (and other babel plugins too? This is a transpiled file with __esModule)
  • html-escaper
  • @ungap/structured-clone
  • @emotion/hash
  • @emotion/cache
  • @emotion/sheet
  • @emotion/weak-memoize
  • @swc/helpers
  • @floating-ui/dom
  • css-declaration-sorter
  • @floating-ui/core
  • marked
  • redux (still continuing my testing by going through the list..)

joyeecheung avatar Mar 09 '24 06:03 joyeecheung

Heya Joyee! Thanks!

I guess it’s the import for ESM and then a default condition for CJS. Feels a bit weird to do it that way instead of the inverse, or instead of the require vs import mutually exclusive conditions.

Did you find more? I’ll investigate next time I crawl. Or, PR welcome!

wooorm avatar Mar 12 '24 11:03 wooorm

I guess it’s the import for ESM and then a default condition for CJS.

Yes, this seems quite common actually. Also many of them have "type": "module" at the top level package.json, but also another package.json in a folder that has "type": "commonjs", and then in the top level package.json they have conditional exports require or default pointing to that folder (axios, parse5, html-escaper, etc.). Some of them have "type": "module" but then the files resolved via main or exports have .cjs extension (e.g. marked) so could also be loaded just fine as CJS.

I've put the ones I've found (and the script used to load them with require()) in https://github.com/joyeecheung/test-require-esm/blob/main/dual.cjs

joyeecheung avatar Mar 15 '24 16:03 joyeecheung

thanks, done!

wooorm avatar May 27 '24 11:05 wooorm