Webpack will include all of d3.js in the bundle when doing import { select } from 'd3'
as seen in the following bundle visualization. The problem can be solved by doing import { select } from 'd3-selection'
but this defeats the purpose of automatic tree shaking somewhat.
Tree shaking does appear to work in simple cases on our non-library code.
We use "modules": false
in our .babelrc
in order to retain the module syntax and use 'module'
resolve in our webpack.config.js resolve: { mainFields: ['module', 'browser', 'main'] }
in order to select d3's module based code. As you can see the imported node_modules/d3/index.js is partitioned in ES6 modules instead of a monolithic browser bundle or CommonJS export.
Should this be posted as an issue on the webpack github page or am I doing something wrong? This is using all the latest versions of the libraries ([email protected]
, [email protected]
, etc)
edit: Seems like this is related to the following issues:
Basic Webpack ConfigurationWebpack only does tree shaking when doing minification, which will only occur in production model. Second, you must set the optimization option “usedExports” to true. This means that Webpack will identify any code it thinks isn't being used and mark it during the initial bundling step.
The principle behind tree shaking is as follows: You declare all of your imports and exports for each of your modules. Your bundler (Webpack, Rollup, and so on) analyzes your dependency tree during the compilation step. Any provably unused code is dropped from the final bundle, or 'tree-shaken'.
What is the current behavior? Webpack 2 support tree shaking and removal of dead code but this does not work for CSS. If we have a javascript file which exports different CSS files and we only import some of then, then css loader does not tree shake and remove the unused CSS.
It relies on the import and export statements to detect if code modules are exported and imported for use between JavaScript files. In modern JavaScript applications, we use module bundlers (e.g., webpack or Rollup) to automatically remove dead code when bundling multiple JavaScript files into single files.
Tree shaking will only work for ES6 modules because they can be statically analyzed. AMD/CommonJS which a lot of libs publish can't be, which is why you're probably not seeing any tree shaking happening. Please see https://advancedweb.hu/2017/02/07/treeshaking
UPDATE: There appears to be a new webpack plugin that is capable of tree shaking Common JS modules, https://github.com/indutny/webpack-common-shake. Please note, that the repo says it's in alpha.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With