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)