webpack4 进阶篇3 ——JS tree-shaking 使用指南 & 原理介绍

本文长期更新,如有错误或者补充,欢迎留言 ~
关注一下不迷路 ~

tree-shaking 摇树,通过摇晃树把枯叶摇下来,代码中指去除无用的代码。

使用步骤


  1. package.json添加 sideEffects配置
"sideEffects": [ 
    "*.css",
    "*.vue" // 如果是vue项目
]
  1. webpack mode 配置为production

注意:

  • vue项目
    由于.vue文件混合了css(单独写没事),导致他们是有副作用的,如果tree-shaking会把css摇掉
    总而言之,tree-shaking对vue项目没啥效果
  • * 检查有副作用的模块,将他们加入到sideEffects当中

原理简述


实际上共做了2件事

1. 去除未引用ES模块变量


如果一个.js文件,导出(export)的变量并未被使用,则删除他们。

示例

模块a.js中导出了2个变量square cube

//a.js
const square = (x) => {
  console.log(1111111)
  return x * x;
}

const cube = (aaa) => {
  console.log(2222222)
  return aaa * aaa * aaa;
}

export {square, cube}

但在index.js中引入此模块时只用到了第一个变量

//index.js
import {square} from './a.js';

console.log(square);

打包后,a.js中的第二个变量会被删除

原理
  • webpack会在打包时识别未使用的导出的变量(函数 类 对象等),将其标记为unused harmony export xx
    需要开启 optimization.usedExports
  • 压缩插件(TerserPlugin)对标记部分进行删除
    需要开启 optimization.minimize

注意:

  1. 如果有副作用文件需要使用package.json中的sideEffects配置,这需要开启 optimization.sideEffects
  2. 未导出但内部使用了的变量不会被删除
  3. 即使导出的变量被其他模块导入了,但未使用,依然会被删除
  4. bable(7)转义并不会产生影响

2. 去除 dead code


dead code 指不执行或只定义不使用的代码

原理

压缩插件(TerserPlugin)通过遍历作用域识别这些dead code,并进行删除

示例

打包后下面的1-4都会被删除

const square = (x) => {

  // 1 不执行
  if (false) {
    console.log(1111)
  }
  // 2 只定义不使用
  function a() {
    console.log(6666)
  }
  // 3 只定义不使用
  var b = 2222;
  return x * x;
  // 4 不执行
  const c = 3333;
}

答疑


  1. tree-shaking 到底有啥用?
    (1)针对模块缩减代码:导出的变量没被使用,那么删除这个变量
    (2)针对代码块缩减代码:删除不执行或只定义不使用的代码

  2. 我的ui库是不是可以通过tree-shaking大幅度缩减代码?
    并不会。
    因为大多数库只是导出一个变量,当然有的支持按需引入是可以的,比如element-ui

参考

  • tree-shaking
  • 你的Tree-Shaking并没什么卵用

你可能感兴趣的:(webpack4 进阶篇3 ——JS tree-shaking 使用指南 & 原理介绍)