javascript tree shaking 中,命名导入(named import)的使用必须严格对应模块导出的标识符名称,且代码中不能存在对该标识符的副作用引用。只要确保导入路径正确、未触发副作用,打包工具即可通过静态分析移除未使用的导出。

如何配置构建工具以启用 Tree Shaking
在 Webpack 或 Rollup 等现代构建工具中,Tree Shaking 默认处于开启状态,但前提是代码必须符合 ES Module (ESM) 规范。你需要将 package.json 中的 type 字段设置为 module,或者使用 .mjs 后缀,以确保解析器能识别 ESM 语法。同时,务必设置 mode: 'production' 或显式启用压缩插件,因为开发模式通常为了调试方便会保留所有代码。配置完成后,工具会自动标记未被引用的导出函数为死代码并剔除。

// package.json
{
"name": "my-app",
"version": "1.0.0",
"type": "module"
}
// main.js
import { add } from './utils.js';
console.log(add(1, 2));
// utils.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
预期结果:构建后的产物中仅包含 add 函数的逻辑,subtract 函数被完全移除。
为什么某些命名导入无法被摇树优化
即使使用了正确的命名导入语法,如果导出的模块内部存在“副作用”(Side Effects),Tree Shaking 也会失效。副作用指的是模块加载时执行的初始化代码,如全局变量修改、DOM 操作或 API 调用。当构建工具检测到模块有副作用时,为了安全起见,它会假设该模块的所有导出都可能被依赖,从而放弃优化。解决此问题的方法是在 package.json 中明确声明 "sideEffects" 字段,列出包含副作用的文件,其余文件将被视为纯函数模块进行优化。

// package.json
{
"name": "my-app",
"sideEffects": ["./src/polyfill.js", "*.css"]
}
// src/utils.js (无副作用)
export const PI = 3.14;
export function getArea(r) {
return PI * r * r;
}
// src/polyfill.js (有副作用)
if (!Array.prototype.flat) {
Array.prototype.flat = function() { ... };
}
预期结果:utils.js 中的未使用导出被移除,而 polyfill.js 始终被引入以保证兼容性。
命名导入与默认导入在摇树优化中的行为差异
在 Tree Shaking 场景下,命名导入和默认导入的主要区别在于它们对模块整体性的影响。命名导入允许精确地只提取所需的函数或变量,例如 import { map } from 'lodash-es',这能最大程度地减小包体积。相比之下,默认导入 import _ from 'lodash' 通常会引入整个库,除非使用的是像 lodash-es 这样专门针对 ESM 优化的版本。此外,命名导入更容易受到重命名(Renaming)的影响,如果开发者在导入时使用了别名 import { add as sum },只要 sum 被使用,add 就会被保留,这与直接引用原始名称的行为一致,不会导致额外的代码膨胀。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











