DEV Community

tmhao2005
tmhao2005

Posted on

webpack compiles node_modules

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) 
Enter fullscreen mode Exit fullscreen mode

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; 
Enter fullscreen mode Exit fullscreen mode

Next, write a simple snippet to import foo in cjs style:

const foo = require('foo'); console.log(foo); 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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)