tree shaking
# 1. 概念
1 个模块可能有多个⽅法,只要其中的某个⽅法使⽤到了,则整个⽂件都会被打到 bundle ⾥⾯去,tree shaking 就是只把⽤到的⽅法打⼊ bundle ,没⽤到的⽅法会在 uglify 阶段被擦除掉。
- return 后面的代码
- 只声明,未使用的函数
- 只引入,未使用的代码
# 2. 限制
- 使用ES Module规范模块,,才能执行Tree Shaking
- Tree Shaking依赖于ES Modules的静态语法分析
# 3. Tree-shaking 原理
利⽤
ES6
模块的特点:- 只能作为模块顶层的语句出现
- import 的模块名只能是字符串常量
- import binding 是 immutable的 代码擦除: uglify 阶段删除⽆⽤代码
开发模式:
- usedExports
- sideEffects
现象:构建后的代码存在⼤量闭包代码
导致:
⼤量作⽤域包裹代码,导致体积增⼤(模块越多越明显)
运⾏代码时创建的函数作⽤域变多,内存开销变⼤
模块转换分析:
被 webpack 转换后的模块会带上⼀层包裹
import 会被转换成 __webpack_require
打包出来的是⼀个
IIFE
(匿名闭包)modules 是⼀个数组,每⼀项是⼀个模块初始化函数
通过
WEBPACK_REQUIRE_METHOD(0)
启动程序__webpack_require
⽤来加载模块,返回module.exports
# 4. scope hoisting 原理
原理:将所有模块的代码按照引⽤顺序放在⼀个函数作⽤域⾥,然后适当的重命名⼀ 些变量以防⽌变量名冲突
对⽐: 通过
scope hoisting
(作用域提升)可以减少函数声明代码和内存开销scope hoisting
使⽤: webpack mode 为 production 默认开启,必须是 ES6 语法,CJS 不⽀持
new webpack.optimize.ModuleConcatenationPlugin()
# 5. 开发模式:
# usedExports
开启:
- optimization.usedExports(标记没用的代码)
- /* unused harmony export xxxx */
- terser-webpack-plugin(删除没用的代码)
- optimization.minimize: true(删除unused harmony export xxx 标记的代码)
- webpack4 需要单独安装(webpack5 无需安装)
兼容性问题
Tree Shaking 与Source Map 存在兼容性问题
开启Tree Shaking
Source Mao模式只能选择一下四种:
devtool:source-map|inline-source-map|hidden-source-map|nosources-source-map
# sideEffects
- 副作用:
- 无副作用:如果一个模块单纯的导入导出变量,那它就无副作用
- 有副作用:如果一个模块还修改其他模块或者全局的一些东西,就有副作用
- 修改全局变量
- 在原型上扩展方法
- css的引入
- sideEffects的作用:把未使用但无副作用的模块一并删除
- 对于没有副作用的模块,未使用代码不会被打包(相当于压缩了输出内容)
- 开启副作用:(webpack.config.js)
- optimization.sideEffects: true
- 标识代码是否有副作用(package.json)
- sideEffects
- false: 所有代码都没副作用
- true: 所有代码都有副作用
- 数组:告诉webpack哪些模块有副作用,不删除
- sideEffects