Tree shaking用法及原理

1,106 阅读2分钟

什么是tree shaking

tree shaking 是一种代码优化技术,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

webpack 2 正式版本内置支持 ES2015 模块(也叫做 harmony modules)和未使用模块检测能力。新的 webpack 4 正式版本扩展了此检测能力。

tree shaking作用

它的作用就是将程序中没有用到的代码在打包编译的时候都删除掉,这样能减少打包后包的文件大小,减少程序执行的时间。

哪些代码属于dead-code

  • 代码不会被执行,不可到达

  • 代码执行的结果不会被用到

  • 代码只会影响死变量(只写不读)

// a.js
export const a = 'a';
export const b = 'b';    // 不导出,删除
export const c = 'c';    // 导出不引用,删除

// index.js 
import { a, c } from './a.js'; 
console.log(a);

if(false) {             // 不会执行的代码,删除
  console.log('delete');  
}

tree-shaking特点

  • tree shaking 是基于 ES6 模块机制,意味着如果你引用不同的文件就需要遵循 ES6 的模块规范。

  • ES6的模块引入是静态分析的,故而可以在编译时正确判断到底加载了什么代码。

  • 分析程序流,判断哪些变量未被使用、引用,进而删除此代码。

development环境下

开发环境下不需要tree-shaking,optimization配置 usedExports: true,打包文件中会展示模块提供的变量,以及使用了的变量,并不会把dead code剔除掉。

optimization: {
    usedExports: true
}
/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/*! no exports provided */
/*! all exports used */


/***/ "./src/utils.js":
/*!**********************!*\
  !*** ./src/utils.js ***!
  \**********************/
/*! exports provided: a, cadfadsfadffafdasfadsfsdf, c */
/*! exports used: a */

什么是sideEffects

sideEffects 的作用是让 webpack 去除 tree shaking 带来副作用的代码。

sideEffects用法

"side effect(副作用)" 的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。

注意,所有导入文件都会受到 tree shaking 的影响。这意味着,如果在项目中使用类似 css-loader 并 import 一个 CSS 文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:

{
  "name": "your-project",
  "sideEffects": ["./src/some-side-effectful-file.js", "*.css"]
}

参考文章

你的Tree-Shaking并没什么卵用