Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do material-ui modules show in both node_modules and src after Webpack 4 tree shaking?

The Cloud Native Interactive Landscape is an open-source, browser-only application that loads a static React app for visualizing the cloud native ecosystem:

  • Try the app
  • View source

You can interactively view the results of webpack-bundle-analyzer and here is a snapshot:

Webpack Bundle Analyzer image

I don't understand why @material-ui/core/es appears in both node_modules and src. More generally, I'm trying to understand if our tree-shaking is optimally implemented, or if there's a better way to configure it. I would also appreciate hearing if we're optimally tree-shaking lodash. (Note that we're only targeting evergreen browsers.)

Please feel free to fork the repo and edit webpack.config.prod.js. If you open a pull request, Netlify will build and deploy a test server and you can check for results under test-server-url/report.html.

like image 488
Dan Kohn Avatar asked Nov 24 '18 18:11

Dan Kohn


1 Answers

So let me preface that the es name was poorly chosen. src would be much more fitting since it's just that: The untranspiled source code. This is documented in the docs under minimizing bundlesize

With webpack 4 and proper module entries in the respective package.json you should automatically pull in the esmodule version of those packages. The esmodule version is responsible for most of the tree-shaking optimization in webpack.

@material-ui/core already has a proper entry. This is however only at the top level an esmodule version. The actual components are then written with commonJS which does not allow tree-shaking in webpack. We have an open PR but we might wait for the next major since we don't test on the compiled files which makes changes to the build scary.

As to why this appears as a concatenated module I can't help you with that. While investigating I made the same observation (https://github.com/eps1lon/material-ui-treeshaking). It is probably an issue with the bundle-analyzer and has no actual impact on the generated chunks (e.g. https://github.com/webpack-contrib/webpack-bundle-analyzer/issues/188).

Overall I would recommend not using the es version and simply letting webpack target the module entry. It allows tree shaking for the bulk of the package but you loose out on some micro-optimization. I tested transpiling everything to esmodules and made some improvements to the stat size of a bundle from 200KB to 180KB but hit some gzip deoptimization which increased the gzipped size by 1KB (meme version). So don't stress about tree-shaking for every tiny file.

like image 87
epsilon Avatar answered Sep 21 '22 18:09

epsilon