我刚刚将我的 react 应用程序从 webpack 1 更新到 webpack 2。但是,我的包大小增加了 ~30Kb。我希望捆绑包的大小会减小,我如何确认摇树有效。为什么增加?
2 回答
TL;DR: As of version 2.3, webpack doesn't have any tree shaking. It merely uses UglifyJS to remove unused code.
First we must define what is tree shaking.
Stackoverflow defines it as "dead code elimination algorithm for modern javascript".
Webpack clarifies that it relies on ES2015 module import/export for the static structure of its module system.
Rollup (which originally popularized the term) also has a similar explanation.
So we can deduce a specific definition: static exclusion of unused ES module exports.
Now, let's see which stages of transformation each module usually has:
- babel-loader is fed an entry point which is a javascript file in some module format. Babel can either transform it to another module format of leave it as is (
module: false
) - webpack will statically parse the file and find imported modules (using some sort of regexp)
- webpack will either transform the module format (if babel doesn't tranform it already) or add some wrappers (for commonjs modules)
- imported module becomes an entry point and goes to babel-loader
- after all modules are loaded and transformed, uglify will process the result bunle and remove unused code (
unused: true
)
Now, we can see that while uglify can remove unused exports it doesn't actually rely on ES module syntax. It's just a general purpose dead code elimination so it can't be defined as "Tree shaking".
So how can we confirm whether webpack has tree shaking?
- First of all, all the code must be in ES module format.
- As it was already mentioned in another answer we must disable Uglify.
- We also must disable babel's module transformation as we can't know whether a module is used at that phase.
And now if webpack actually implements a tree shaking algorithm we can confirm it by looking at the bundle size of this entry point:
import { keyBy } from 'lodash-es'; // lodash is in ES module format
console.log(keyBy([{ key: 'value' }], 'key'));
If webpack does have tree shaking the result should be tens of kilobytes. If it doesn't it would be half a megabyte or more.