Tree Shaking

一、解决的问题

Tree-shaking 去除无用代码,从而减小文件体积。

二、什么是Tree Shaking

Tree-shaking (摇树) 是一个术语,通常指通过打包工具"摇"我们的代码,将未引用代码 (Dead Code) "摇" 掉。在 Webpack 项目中,有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝,虽然依赖了某些模块,但其实只使用其中的某些方法,通过 Tree Shaking ,将没有使用的方法摇掉,这样来达到删除无用代码的目的。

三、原理

程序会从入口文件出发扫描所有的模块依赖,以及模块的子依赖 ,然后将它们链接 起来形 一个 "抽象语法树 " (AST)。随后,运行所有代码 ,查看哪些代码是用到过的做好标记 。最后,再 "抽象语法树"中没有用到的代码"摇落" 。经历这样一个过程后,就去除了没有用到的代码。

前提是模块必须采用 ES6 Module 语法,因为 Tree Shaking 依赖 ES6 的静态语法:import 和 export。不同于 ES6 Module,CommonJS 支持动态加载模块 ,在加载前是无法确定模块是否有被调用 ,所以并不支持 Tree Shaking 。如果项目中使用了 babel 的话, @babel/preset-env 默认将模块转换成 CommonJs 语法,因此需要设置 module:false

CommonJS 与 ES6 Module 模块的依赖的区别在于,CommonJS 是动态的 ,ES6 Module 是静态的

CommonJS 导入时,require 的路径参数是支持表达式的,路径在代码执行时是可以动态改变的,所以如果在代码编译阶段就建立各个模块的依赖关系,那么一定是不准确的,只有在代码运行了以后,才可以真正确认模块的依赖关系,因此说CommonJS 是动态的。

ES6 模块不是对象,它的对外接口只是一种静态定义,在代码编译,静态解析阶段就会生成,这样我们就可以使用各种工具对JS模块进行依赖分析,优化代码。

四、sideEffects

webpack v4 开始新增了一个 sideEffects 特性,通过给 package.json 加入 sideEffects: false 声明该包模块是否包含副作用,从而可以为 Tree Shaking 提供更大的优化空间。 举例说明

arduino 复制代码
js
复制代码
// a.js
// 无副作用,仅仅是单纯的 export
function a () {
  console.log('a')
}
export default {
  a
}
javascript 复制代码
js
复制代码
// b.js
function b () {
  console.log('b')
}

// 执行了特殊行为
Array.prototype.fun = () => {}

export default {
  b
}

如果 a 在 import 后未使用,Tree Shaking 完全可以将其优化掉;但是 b 在 import 后未使用,但因为存在他还执行了为数组原型添加了方法,副作用还是会被保留下来 。这时就需要使用 sideEffects: false ,可以强制标识该包模块不存在副作用,那么不管它是否真的有副作用,只要它没有被引用到,整个 模块/包 都会被完整的移除。

如果你的项目中存在一些副作用代码 b 需要被保留下来,比如 polyfill、css、scss、less 等,可以按下面方法一样配置;保证必要的代码不被 Tree Shaking

json 复制代码
json
复制代码
// package.json
{
  "name": "your-project",
  "sideEffects": ["./src/b.js", "*.css"]
}

四、配置条件

  • 使用 ES6 Module 语法(即 importexport)。
  • 确保没有 @babel/preset-env等工具将 ES6Module 语法转换为 CommonJS 模块。
  • optimization: { minimize: true, usedExports: true }
  • 使用支持 Tree Shaking 的包。

五、引用

# 带你了解 Tree Shaking

相关推荐
梦帮科技11 分钟前
GRAVIS v4.0:基于Web的极速套利架构设计与实时数据流实现
前端·人工智能·rust·自动化·区块链·智能合约·数字货币
爱勇宝42 分钟前
办公资料反复修改、补传、交接混乱,我做了个桌面工具来解决这件事
前端·后端·程序员
微信开发api-视频号协议1 小时前
企业微信外部群开发自动化实践过程
java·前端·微信·自动化·企业微信·ipad
甲维斯1 小时前
Fable5:20美金的顶级设计师!
前端·人工智能
kyriewen2 小时前
我同时用了 Claude Code、Cursor 和 Codex,说说三个工具的真实差距——2026 年选错工具比不用 AI 更浪费时间
前端·ai编程·claude
Jackson__2 小时前
为了拯救我的腰椎和颈椎,我做了款浏览器插件!
前端·javascript·开源
闲猫2 小时前
Python FastAPI + SQLAlchemy 入门教程:从零搭建你的第一个 Web 应用
前端·python·fastapi
林小帅3 小时前
NestJS v11 + Prisma v7 ESM 迁移配置解析
前端·javascript·后端
IT_陈寒3 小时前
React的setState竟然不是立刻生效的,害我调试半天
前端·人工智能·后端
简简单单就是我_hehe3 小时前
前端埋点日志解决方案:完整 User-Agent 解析工具实现,爬虫识别、设备品牌、操作系统、浏览器版本全解析(附完整源码)
前端·爬虫