I found out an interesting use case as we import a module (just call it foo
) which supports both node and browser. But with the same import of foo
, webpack
would end up a different result in the browser. Let's have a look at the following example:
Firstly, assume to have a package foo
like below:
- dist
-- index.js (cjs)
-- index.module.js (esm - mostly for browser)
The content of foo
would look like in both modules:
// dist/index.js
// the content can be `cjs` or `umd`, for example:
module.exports = 1;
// dist/index.module.js
export default 1;
Next, write a simple snippet to import foo
in cjs
style:
const foo = require('foo');
console.log(foo);
Then run on Node:
const foo = require('foo');
// since above line of code ref to dist/index.js so will work as expected
console.log(foo); // 1
Finally, run on browser via webpack
after having been transformed:
// webpack auto select `esm` module by default
var foo = __webpack_require__("./node_modules/foo/index.module.js");
// __webpack_require__ will turn the foo object to be like:
// { default: 1 }
// As a result of that, this code won't work as expected
console.log(foo); // undefined
To sum up, we have to be careful with the package (foo
) which supports running on node/browser to avoid unexpected result as above. As I know most of packages are now being implemented that way. If you write code in Typescript or Esnext style, you can enable the configuration { esModuleInterop: true }
to import helper to sort out the issue in case of Typescript.
Thanks for reading!
Top comments (0)