我们先来写一个例子,在 src 目录下,创建一个文件 math.js 。它导出两个方法。如下
export const add = (a,b) => {
console.log(a+b);
}
export const minus = (a,b) => {
console.log(a-b);
}
然后,在 index.js 中引入,如下。
import {add} from './math.js';
add(1,2);
然后我们打包项目。
npm run bundle
下面是打包后的js 文件中的一部分内容,可以看到,它将minus 方法也打包进去了。但是这个方法,我们并没有任何地方使用它。
webpack 2.0 以后就提供了tree shaking 功能。它能将不使用的代码,不打包。
要注意:
Tree shaking 只支持 ES module (即只支持 ES6 的模块引入 import ,不支持像CommonJs require)
下面,我们去配置Tree shaking
webpack 的模式为 ‘development’时,默认是没有 Tree shaking 功能的。那么我们需要这样配置,在plugins 配置项的后面,添加一个配置项 optimization,如下。
optimization: {
usedExports: true
}
然后,我们再去package.json 中再去写一个配置项 "sideEffects" 。使用这个配置项,是因为,只要使用了Tree Shaking,那么webpack 会把模块都使用Tree Shaking 方式打包,但是当我们使用babel 的 import '@babel/polyfill' 时,这个模块其实没有导出任何内容,它内部会在全局对象window下绑定一些对象(比如Promise)。如果使用了Tree Shaking,那么它可能就被Shaking 掉了。那么 "sideEffects" ,就把这个模块写进来。如下。
{
"name": "websiteTest",
"sideEffects": ["@babel/polyfill"]
...
一般,我们还会把css 文件申明一下,不要进行Tree Shaking ,如下
{
"name": "websiteTest",
"sideEffects": ["@babel/polyfill","*.css"]
...
当然,没有这种需要申明的模块时,可以把"sideEffects" 的值设为 false, 如下。
{
"name": "websiteTest",
"sideEffects": false,
...
然后,可以打包了。npm run bundle
其实我们发现,打包后,minus 还是会在打包后的文件中。
当我们把webpack.config.js 中的mode 设置为 “production” 后,Tree Shaking 才会真正的Shaking 。
production 时,很多地方都默认配置好了,我们就不需要写刚刚的 optimization 配置项了,当然package.json 中的"sideEffects"还是需要的。