一、Tree shaking是什么
Tree shaking 是一个通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code) 行为的术语。
它依赖于ES2015中的 import 和 export 语句,用来检测代码模块是否被导出、导入,且被 JavaScript 文件使用。
二、Tree shaking的原理
2.1 原理
Tree shaking的本质是移除掉无用的js代码。无用代码移除存在于各种compiler中,compiler会根据代码的export和import的关系,判断出一些代码没有用到,或者注释掉了等,删除不会影响逻辑,然后把他们移除掉,这个过程就是DCE(dead code elimination)。
在ES6里引入了ES Module这样的静态的模块,ES Module依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是tree-shaking的基础。能够把依赖树静态地推导出解析语法树。
2.2 在webpack中配置
在webpack2中就支持了Tree shaking,在webpack4中,需要将mode设置为production即可开启Tree shaking
同时,也可以通过package.json的 sideEffects属性作为标记,向compiler 提供提示,表明项目中的哪些文件是 “pure”,由此可以安全地删除文件中未使用的部分。
{
"name": "tree-shaking",
"sideEffects": false
}
如果所有代码都不包含副作用,可以简单地将该属性标记为false,来告知 webpack,它可以安全地删除未用到的export导出。
{
"name": "tree-shaking",
"sideEffects": [
"./src/common/polyfill.js"
]
}
如果代码有一些副作用,那么可以改为提供如上数组
三、Tree shaking为什么摇不动
3.1 Babel
Babel可以把ES6及以上的代码转化成浏览器支持的代码。也正是因为Babel的出现,才让FEr不用去考虑各种浏览器的兼容的问题。
但是也正是因为Babel的编译,让很多代码可能有了sideEffects。Babel默认把所有的module编译成require的形式,但是这个是动态的模块,webpack不能进行Tree shaking,所以要在.babelrc里处理一下,不要把import转换成require。
{
"presets": [
["env", {
"modules": false //关键点
}],
"stage-2",
"react"
]
}
3.2 代码的问题
在写代码的时候,不要写一些IIFE里引用外部变量的问题,多写一些pure的函数。