wooorm / npm-esm-vs-cjs

Data on the share of ESM vs CJS on the public npm registry

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Some modules labeled 'esm' are dual

joyeecheung opened this issue · 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..)

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!

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