loaders-test
loaders-test copied to clipboard
commonjs-extension-resolution-loader breaks packages using module and exports.* fields
Because commonjs-extension-resolution-loader relies on resolve/async
which is an implementation of require.resolve(), specifying it as a Node.js loader causes ESM packages to break.
For example,
index.js
import isValidAbn from 'is-valid-abn';
works fine with node --experimental-specifier-resolution=node index.js
, but with node --experimental-loader=./commonjs-extension-resolution-loader index.js
breaks with:
file:///…/index.js:2
import isValidAbn from 'is-valid-abn';
^^^^^^^^^^
SyntaxError: The requested module 'is-valid-abn' does not provide an export named 'default'
at ModuleJob._instantiate (node:internal/modules/esm/module_job:123:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:189:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
at async loadESM (node:internal/process/esm_loader:91:5)
at async handleMainPromise (node:internal/modules/run_main:65:12)
What makes the error go away:
- Monkey patching
main
field inis-valid-abn
'spackage.json
to point to ESM entry file - Monkey patching
resolve
package to include:if (pkg && pkg.module) { if (typeof pkg.module !== 'string') { var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); mainError.code = 'INVALID_PACKAGE_MAIN'; return cb(mainError); } if (pkg.module === '.' || pkg.module === './') { pkg.module = 'index'; } loadAsFile(path.resolve(x, pkg.module), pkg, function (err, m, pkg) { if (err) return cb(err); if (m) return cb(null, m, pkg); if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb); var dir = path.resolve(x, pkg.module); loadAsDirectory(dir, pkg, function (err, n, pkg) { if (err) return cb(err); if (n) return cb(null, n, pkg); loadAsFile(path.join(x, 'index'), pkg, cb); }); }); return; }
This, obviously, doesn't get the support for exports
field back.
I was using this package, so I had to find solutions as well
This seems to work https://www.npmjs.com/package/extensionless
disclaimer: I'm not involved with the project