When you have an ESM module like this:
// greetings.js
export const hello = 'hello';
export const hi = 'hi';
and you try to import it using default export:
import greatings from './greetings.js';
You will get The requested module './greetings.js' does not provide an export named 'default'
error, which is expected.
But for some packages, like yup
, I noticed you can import it like this:
import yup from 'yup';
if you install Yup and check index.esm.js
, you will notice, it also doesn't have any default export. so how we are able to import it using default?
If you want to say, Yup is shipped with a CommonJS module (index.js
), I have to say yes, but some other packages like rotating-file-stream
are also shipped with a CommonJS module, but we get the does not provide an export named 'default'
error when we try to import it using default import.
I trid these:
import yup from 'yup';
console.log(yup);
and
import rfs from 'rotating-file-stream';
console.log(rfs);
first one works, but second one doesn't, why?!
P.S. I tested using latest versions of both yup
(1.4.0) and rotating-file-stream
(3.2.3).
The actual reason for this behavior is the fact that NodeJS ignores the module
filed in the yup
package. so it loads the CJS module.
When NodeJS loads a CJS module, it puts everything in module.exports
inside the default ESM export. so we can load yup
like import yup from 'yup';
.
But in the other hand, rotating-file-stream
has an exports
field in the package.json
file, which is supported by NodeJS, so NodeJS is able to load the actual ESM module because of it.
When NodeJS loads the actual ESM module, It treats it as it is, and because the ESM module of rotating-file-stream
has no default export, we see the error.
See: https://nodejs.org/api/esm.html#interoperability-with-commonjs