10. 为什么 Tree Sharking 要求使用 ES 模块?
约 389 字大约 1 分钟
2025-06-21
Tree Shaking 依赖 ES6 模块语法 (import / export
) 而非 CommonJS (require / module.exports
),这是由两种模块系统的本质差异决定的:
ES 模块是静态的
- 导入导出必须在顶层作用域(不能在条件语句中)
- 导入的模块名只能是静态字符串
- 所有依赖关系在代码运行前就可以确定
import()
动态导入- 如果路径是静态字符串,Tree Shaking 可以静态分析,移除未使用代码。
- 如果路径是动态拼接,Tree Shaking 无法对其静态分析。
import { a } from "./moduleA.js";
// 动态导入返回 Promise,但仍支持 Tree Shaking
import("./module").then((module) => {
module.usedFunction();
});
let moudle_name = business == "a" ? "moduleA" : "moduleB";
// 无法进行静态分析,Tree Shaking 失效
import(`./${moudle_name}.js`).then((module) => {
module.usedFunction();
});
CommonJS 是动态的
require()
可以在任何地方调用(包括条件语句和函数内)require()
导入的模块名可以是静态字符串,也可以是变量- 导出可以被条件语句动态修改
- 所以依赖关系在运行时才能确定
const helper = require("./helper.js"); // 动态的,helper.js 可能在运行时改变
if (Math.random() > 0.5) {
module.exports.bar = function () {
/*···*/
}; // 条件导出
}
总结
CommonJS 的动态性使得静态分析变得非常困难,打包工具无法在编译时准确判断哪些代码会被使用。而 ES6 模块的静态特性,使得打包工具可以安全地进行分析和移除未使用代码。
更新日志
2025/8/24 08:17
查看所有更新日志
e7112
-1于