webpack摇树的原理的实现小结

 更新时间:2026年05月11日 09:21:07   作者:秀秀不只会前端  
Webpack 的 Tree Shaking(摇树)是一项用于消除 JavaScript 上下文中未引用代码的优化手段,它能有效减小打包体积,下面就来详细的介绍一下,感兴趣的可以了解一下

Webpack 的 Tree Shaking(摇树)是一项用于消除 JavaScript 上下文中未引用代码的优化手段,它能有效减小打包体积。

核心原理

Tree Shaking 的本质是 ​死代码消除​,它依赖 ​ES6 模块(ESM)的静态语法结构​。

静态分析​:ESM 的 import/export 语句必须位于模块顶层(注意:模块顶层不是模块文件顶部的意思,模块顶层可以认为是模块文件中最外层的代码区,不在任何函数、类或代码块内部),且模块路径必须是字符串常量。这样, Webpack 在编译阶段就能构建出完整的模块依赖图,无需运行代码即可分析出哪些导出值未被其他模块使用 。

这时有同学就会问了,那么动态 import 怎么判断呢?

其实,还是那个关键点,是否可以被“静态分析”。

// ❌ 难以静态分析,无法使用摇树优化
const componentMap = {
  basic: () => import('./BasicComponent'),
  advanced: () => import('./AdvancedComponent')
};
const getComponent = componentMap[userInput]; // 运行时才能确定

// ✅ 条件明确,可以被静态分析
if (import.meta.env.VITE_APP_MODE === 'basic') {
  const BasicComponent = await import('./BasicComponent');
}

标记与清除​:Webpack 的 Tree Shaking 过程大致分为两步。首先,在编译阶段,Webpack 会遍历所有模块,标记(Mark) 出未被使用的导出(通常会在注释中生成类似 unused harmony export 的提示)。随后,在代码压缩阶段,Terser 等压缩工具会真正将标记过的"死代码"清除(Shake) 掉 。

这些配置你是否清楚?

要让 Tree Shaking 生效,需要同时满足以下条件:

  1. 使用 ES6 模块语法​:必须使用 importexport 语句。CommonJS 的 requiremodule.exports动态的,无法在编译时进行静态分析,因此不支持 Tree Shaking 。
  2. 启用生产模式或明确配置​:在 Webpack 配置中,将 mode 设置为 'production' 生产模式下会自动开启相关的优化功能。当然也可以在开发模式下手动配置 optimization.usedExportsoptimization.minimize
// webpack.config.js
module.exports = {
  mode: 'production', // 生产模式自动开启优化
  optimization: {
    usedExports: true, // 启用使用导出分析
    minimize: true     // 启用代码压缩(清除死代码)
  }
};
  1. ​**正确声明副作用 (sideEffects​​)**​:在项目的 package.json 中,通过 sideEffects 属性告知 Webpack 哪些文件是"纯净"的(无副作用),可以安全移除。这能防止具有副作用的文件(如全局样式表、polyfill)被误删 。
// package.json
{
  "sideEffects": false, // 表示整个项目都没有副作用
  // 或明确指定有副作用的文件
  "sideEffects": [
    "**/*.css",
    "./src/polyfill.js"
  ]
}

有同学又会问了,摇树摇的不是 js 吗,样式表 css 怎么会被摇掉呢?

其实,这里指的是导入的但是没有明确导出的 css 样式表,导入导出是明确的 js 语句,css 是“副作用”,比如:

  • 仅导入但未使用任何导出(如 import './style.css'),属于是无形的“使用”,可能被误删
  • 使用 CSS Modules(如 import styles from './Component.module.css'),被视为有被使用的对象(如 styles.className),通常不会被误删

这些问题你遇到过吗?

开发过程中,以下情况仍可能导致 Tree Shaking 失效,看看你有没有遇到过:

  • Babel 配置不当​:Babel 预设 @babel/preset-env 可能会将 ESM 转换为 CommonJS。务必确保其 modules 选项设置为 false,只有 ESM 可以摇树。
// .babelrc
{
  "presets": [["@babel/preset-env", { "modules": false }]]
}
  • 第三方库的模块版本​:优先选择提供 ES6 模块版本的库(如使用 lodash-es 而非 lodash),并采用按需导入的方式 。
// 推荐:按需导入
import { debounce } from 'lodash-es';
// 不推荐:整体导入
import _ from 'lodash';
  • 导出粒度太粗​:尽量使用具名导出而非默认导出对象,有助于进行更精细的分析 。
// 推荐:细粒度导出
export function func1() {}
export function func2() {}

// 谨慎使用:粗粒度导出(不利于分析内部未使用属性)
export default { func1, func2 };

到此这篇关于webpack摇树的原理的实现小结的文章就介绍到这了,更多相关webpack摇树内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何写好你的JavaScript【推荐】

    如何写好你的JavaScript【推荐】

    在实际工作中,我们应该经常会看到一些功能上没有问题,但编码风格和规范却十分糟糕的代码,这往往会让人不敢再往下阅读,甚至会影响阅读者一天的心情。本文的目的在于帮助那些没有养成良好的编码风格,缺乏相应编码规范意识的JavaScript学习者们改善他们的编码形象。
    2017-03-03
  • JS完整获取IE浏览器信息包括类型、版本、语言等等

    JS完整获取IE浏览器信息包括类型、版本、语言等等

    这篇文章主要介绍了JS如何完整获取IE浏览器信息包括类型、版本、语言等等,需要的朋友可以参考下
    2014-05-05
  • 使用百度地图实现地图网格的示例

    使用百度地图实现地图网格的示例

    下面小编就为大家分享一篇使用百度地图实现地图网格的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • JS中LocalStorage与SessionStorage五种循序渐进的使用方法

    JS中LocalStorage与SessionStorage五种循序渐进的使用方法

    这篇文章主要介绍了JS中LocalStorage与SessionStorage五种循序渐进的使用方法,需要的朋友可以参考下
    2017-07-07
  • Javascript访问Promise对象返回值的操作方法

    Javascript访问Promise对象返回值的操作方法

    这篇文章介绍了如何在JavaScript中使用Promise对象来处理异步操作,通过使用fetch()方法和Promise对象,我们可以从后端API获取数据并处理返回值,文章展示了如何使用.then()链式操作和async/await语法来访问Promise对象的返回值,感兴趣的朋友一起看看吧
    2025-03-03
  • javascript 获取鼠标的绝对位置 event

    javascript 获取鼠标的绝对位置 event

    javascript 获取鼠标的绝对位置 event
    2009-06-06
  • js判断字符长度以及中英文数字等

    js判断字符长度以及中英文数字等

    本文为大家介绍下使用js判断字符长度及中英文数字等,下面有个不错的教程,感兴趣的朋友可以参考下
    2013-12-12
  • JS实现移动端在线签协议功能

    JS实现移动端在线签协议功能

    这篇文章主要介绍了JS实现移动端在线签协议功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • js 判断控件获得焦点的示例代码

    js 判断控件获得焦点的示例代码

    本篇文章主要是对js 判断控件获得焦点的示例代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-03-03
  • JavaScript中slice和padEnd的使用小结

    JavaScript中slice和padEnd的使用小结

    本文介绍了JavaScript中slice和padEnd的使用小结,常常被用于数据处理、格式化和切割任务中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12

最新评论