ai / dual-publish

Publish JS project as dual ES modules and CommonJS package to npm
MIT License
187 stars 11 forks source link

update limits and remove sections about bug #15

Open alexander-akait opened 3 years ago

alexander-akait commented 3 years ago

https://github.com/ai/dual-publish#limits

We recommend to avoid default export because of bug in webpack.

It can be misleading because it is not a bug. Explanation - https://github.com/webpack/webpack/issues/7973#issuecomment-419066832 Many other tools (for example babel) work similarly. Even rollup has https://rollupjs.org/guide/en/#outputinterop to control this, because this is a very controversial issue

ai commented 3 years ago

Why Node.js behaviour with CJS to ESM converting for default exports (of module has only default export, export it as object without wrappers) do not work for webpack?

It leads to inconsistency between Webpack and Node.js behaviour and it is the source of the problem.

alexander-akait commented 3 years ago

Using node:

test.mjs

import cjs from './foo.cjs';
import mjs from './foo.mjs';

console.log(cjs);
console.log(mjs);

foo.cjs

// For:
// module.exports = { default: 'cjs' };
//
// output node and webpack is same:
//
// { default: 'cjs' }
module.exports = 'cjs';

foo.mjs

export default 'mjs';

Output:

cjs
mjs

Using webpack

Output:

cjs
mjs
alexander-akait commented 3 years ago

CommonJS doesn't have default export

ai commented 3 years ago

Nope, I am talking about different problem.

You have dual CJS/ESM package:

// lib/index.mjs
export default 'lib'
// lib/index.cjs
module.exports = 'lib'

For Node.js both constructions will work:

require('lib') //=> 'lib'
import lib from 'lib' //=> 'lib'

In Webpack you will have a different result:

require('lib') //=> { default: 'lib' }

It is a open issue and seems like it was fixed in webpack 5, so it is a bug for my understanding of this term. But we can replace this line with recommendations using webpack 5.