mcpField
T
tree-shaking

tree-shaking

github.com/patternsdev开发2571.5k 次安装28 周前更新
代码仓库

关于 tree-shaking

面向 JavaScript 开发者的 Tree Shaking 指南,介绍如何在构建时移除未使用代码以缩小 bundle。内容说明 ES 模块导入方式、模块副作用及其对消除死代码的影响。

主要功能

  1. 01构建时移除未使用代码
  2. 02使用 ES2015 import/export 语法
  3. 03优先采用具名导入
  4. 04在适当时标记无副作用的包
  5. 05说明副作用对摇树优化的影响

适用场景

  1. 01减少 JavaScript bundle 体积
  2. 02避免打包未使用的依赖代码
  3. 03改善页面下载与解析表现

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/patternsdev/skills --skill tree-shaking

安装后在 Claude Code 中输入/tree-shaking确认已加载。

详细介绍

Tree Shaking

我们可能会在打包文件中加入应用里根本没有用到的代码。可以移除这类无用代码,以减小打包文件的体积,避免加载不必要的数据!在将无用代码加入打包文件之前将其移除,这个过程称为 tree shaking。

适用场景

  • 当打包文件中包含来自导入模块的未使用代码时,使用此方法
  • 这有助于精简 JavaScript 打包文件并提升加载性能

说明

  • 使用 ES2015 import/export 语法——只有 ES 模块才能进行 tree shaking
  • 使用命名导入,而不是导入整个模块,以实现有效的 tree shaking
  • 在适当情况下,在 package.json 中将软件包标记为无副作用
  • 请注意,带有副作用的模块无法安全地进行 tree shaking

详情

概念

Tree shaking 旨在从最终的 JavaScript 打包文件中移除永远不会用到的代码。正确执行时,它可以减小 JavaScript 打包文件的体积,并缩短下载、解析和(在某些情况下)执行所需的时间。对于大多数使用模块打包工具(例如 webpack 或 Rollup)的现代 JavaScript 应用,你通常会期望打包工具自动移除无用代码。

将应用及其依赖项看作一棵抽象语法树(我们希望通过“摇动”语法树来优化它)。树中的每个节点都是一个为应用提供功能的依赖项。在 tree shaking 中,输入文件会被视为一个图。图中的每个节点都是一个顶层语句,在代码中称为一个“部分”。Tree shaking 是一种图遍历,从入口点开始,并标记所有遍历到的路径以将其纳入打包文件。

每个组件都可以声明符号、引用符号,并依赖其他文件。即使是“部分”,也会被标记为是否具有副作用。例如,语句 let firstName = 'Jane' 没有副作用,因为如果没有任何代码需要 firstName,移除该语句不会产生任何可观察到的差异。但语句 let firstName = getName() 有副作用,因为即使没有任何代码需要 firstName,移除对 getName() 的调用也会改变代码的含义。

导入

只有使用 ES2015 模块语法(import 和 export)定义的模块才能进行 tree shaking。导入模块的方式决定了该模块是否可以进行 tree shaking。

Tree shaking 会先访问入口文件中所有带有副作用的部分,然后沿着图的边继续遍历,直到到达新的部分。遍历完成后,JavaScript 打包文件只会包含遍历过程中到达的部分。其他部分则会被排除。

假设我们定义了以下 utilities.js 文件:

export function read(props) {
  return props.book
}

export function nap(props) {
  return props.winks
}

接着,我们有以下 index.js 文件:

import { read } from 'utilities';

eventHandler = (e) => {
  read({ book: e.target.value })
}

在这个例子中,nap() 并不重要,因此不会被包含在打包文件中。

副作用

导入 ES6 模块时,该模块会立即执行。即使代码中没有引用模块导出的任何内容,该模块也可能在执行时影响全局作用域(例如 polyfill 或全局样式表)。这称为副作用。即使我们没有引用模块本身导出的内容,_如果_该模块确实导出了值,由于模块导入时的特殊行为,它仍然无法进行 tree shaking!

Webpack 文档对 tree shaking 及如何避免破坏它作出了清晰的说明。

来源

评论

支持 Markdown