webpack高级概念之TreeShaking

webpackhot.jpg

在开始今天的讲解前,我们先来看下面这样一个打包

import "@babel/polyfill";


就是我们之前的代码 ,页面中只引入了babel/polyill
这时候打包完成,在终端会报这样的警告

warning.PNG

什么意思呢?就是我们在babel-loader的配置中设置了"useBuiltIns": "usage"这样的参数,我们就不需要在入口文件中引入@babel/polyfill了。
了解了上面的代码代码警告原因后,我们再写这样一个例子来看一下,我们定义一个模块,在里面导出两个方法

export const add = (a, b) => {
    console.log(a+b)
}
export const minus = (a, b) => {
    console.log(a-b)
}

index.js:

import { add } from './math'

add(1,2)

这时候我们打包看一下,打开./dist目录下的index.html,可以看到已经输出了3,实际上index.js当中,我们只引入了math.js中的add方法,没有引入minus方法,但我们开发main.js中的最终打包你会发现下面这样的内容

minux.PNG

没错,minus方法我们即使没有引入他,但是也打包了他,这显然不是我们所期待的,这会使我们的main.js特别大,我们期待是我引入什么打包什么就可以了。这就是------Tree Shaking的作用了。

Tree Shaking

Tree Shaking翻译成中文为‘摇树’,意思是在打包的过程中,我们把没用的代码摇晃掉。
那么我们如何在webapck中使用tree shaking呢?首先Tree Shaking是只支持ES Module,这一点一定要注意,下面我们就开启Tree Shaking

在webpack中,'development'模式下默认是不开启tree shaking的,那么我们在配置文件中,做如下配置来开启tree shaking

module.exports = {
    optimization: {
        usedExports: true
    },
}

development模式中,我们做了如下配置就开启了tree shaking,其配置项也是顾名思义哈。

sideEffects

然后再packagejson中做如下配置

 "sideEffects": false,

意思是,假如我们开启了tree shaking,那么在打包没一个ES Module的时候,都会使用tree shaking,假如有下面的代码

import "@babel/polyfill"
import { add } from './math'

add(1,2)

我们知道@babel/polyfill没有任何导出,他是将一些兼容写法全局注入到了window对象下面,那么在打包的时候,我们使用tree shaking可能就会将其忽略掉,但实际上我们是需要它的。类似的文件或者包其实有很多,那么我们就需要针对这一类文件做一个特殊的设置,即"sideEffects",如上面所说,假如我们是不希望tree shakingbabel/poyill有任何作用,那么我们只需要配置sideEffects: ["@babel/polyfill"],对于其他的文件中,我们该怎么样怎么样,这里我们设置为"sideEffects": false,是因为我们这里没有使用@babel/polyfill,不需要tree shaking忽略任何文件。
那么什么样的文件,需要我们写进sideEffects里面呢?一般的比如我们的项目中有这样的CSS文件

import './styles.css'
import { add } from './math'

add(1,2)

实际上,只要我们引入了一个模块,tree shaking就会去看,我们导出了什么,引用了什么,没用的就会被干掉,显然'./styles.css'没有任何的导出,那么在打包的时候,就会被忽略掉,导致我们的打包出错,所以我们在项目中一般还会去做这样的配置sideEffects: ["*.css"]意思是,对于任何的css文件,都不去使用tree shaking.

这里我们将了一下sideEffects的作用,下面我们将代码恢复一下,并且将sideEffects: false,开始打包试一下。
可以看出哈,新打包出的文件中,main.js中对于math.js的引用已经变成了这样,

treeshaking.PNG

意思是,我们只使用了add方法,我们会发现哈,其实minus方法其实还在main.js中,但其实tree shaking已经生效了,实际上,webapck在development环境下,即使你开启了tree shaking也不会把代码直接删掉的,只是在代码中做一些提示,这是因为,我们在本地环境下开发的话,我们会做一些调试,比如source map等,如果把这些代码去掉的话,可能对应的行数之类就错了,所以在开发环境下,tree shaking还会保留这些代码,但是在production模式下,这时候tree shaking就会生效了,下面我们来试一下

首先需要注意webapck4.0在production下将自动开启tree shaking,我们除了修改一下之前的source map配置外,将不再手动配置optimization参数,当然,在packagejson中sideEffects还是要配置的
按照上面所说,我们将,mode改为production试一下

module.exports = {
    mode: 'production',
    devtool: 'cheap-module-source-map',
}

打包成功后我们会发现,main.js变成了压缩后的代码,我们只能通过搜索来看一下tree shaking有没有生效,这时候再打包,我们发现,tree shaking已经生效了。只剩下了一个console.log。

写在最后

tree shaking是Webpack中很重要的一个概念,对于webpack打包优化有着重要的作用,在新版本的webpack中,它是默认在生产环境下开启的。不管是在开发环境还是在生产环境下,都别忘了配置sideEffects哦!!!

你可能感兴趣的:(webpack高级概念之TreeShaking)