Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack with module and main transpilation

I've discovered that for some reason, webpack favors module instead of main on package.json.

We have a lot of libraries that export module in ES6 and main transpiled but we end up having stuff not being transpiled then. Taking a couple of famous React modules such as React Bootstrap or React Toolbox

I can see that I'm not going against convention here yet I'm surprised not many people run into this. React needs to run both on the browser and node if SSR is in place so I'm not sure how to proceed here.

Example library here: https://github.com/firstandthird/domodule/blob/master/package.json#L6

Both including node_modules on babel loader and doing the switch indicated on the above solution seem to go against every other thing which, again, surprises me.

Only partial solution I've found is to not exclude node_modules on babel-loader but that seems like it might bite me back.

Here's the relevant portion of Webpack's config.

module.exports = config => ({
  test: /\.m?js$/,
  use: {
    loader: 'babel-loader',
    options: {
      babelrc: false,
      configFile: false,
      presets: [
        [
          '@babel/preset-env',
          {
            targets: config.browserlist,
            useBuiltIns: false,
            modules: false,
            exclude: ['transform-typeof-symbol']
          }
        ]
      ],
      cacheDirectory: true,
      cacheCompression: config.minify,
      compact: config.minify
    }
  }
});

Question is, what's the proper way to either configure Webpack or my libraries. I don't mind changing all the libraries as long as it's a known standard or something that we could be missing here.

like image 260
Antonio Laguna Avatar asked Nov 06 '22 22:11

Antonio Laguna


1 Answers

Well, the standard right now is to provide pkg.main as the webpack's output fully transpiled and bundled and have pkg.module pointing in the transpiled but not bundled output.

Keep in mind that pkg.module should only have import/export from ES6 capabilities and not other stuff (like arrow functions). The unfortunate thing here is that webpack doesn't provide any way to output such a thing. It always puts it's __webpack_require__ stuff.

As you figured out, you can of course adjust your application's config to run babel on the library by including node_modules/yourlibrary if this is a private library that you only use. I don't think that a public library should enforce clients to transpile it every time, especially if there are specific rules or plugins that should apply.

The other solution that libraries use is to just take the source code and run babel only on top of it, without any webpack. This of course will work, but advanced configurations with webpack specifics (like alias,etc) will just fail.

Another solution is to use rollup as a bundler for libraries that seems to have these capabilities out of the box.

There is an open issue in webpack with more information if you are intrested.

Here is also a page from rollup that describes this concept.

like image 96
Alex Michailidis Avatar answered Nov 10 '22 00:11

Alex Michailidis