在 Webpack 进行模块打包时,ES Module 中的 import 语法与 CommonJS 中的 require 语法在模块依赖解析、输出结构以及 Tree Shaking 支持上有何具体差异?
考察说明
考查对前端模块化规范差异及其在打包工具中行为的理解。
回答思路
- 【回答框架 1】ES Module 是 ECMAScript 标准,采用静态导入导出,依赖关系在编译时确定,支持 Tree Shaking;CommonJS 是 Node.js 的模块系统,使用 require 动态加载,依赖关系在运行时确定,难以静态分析。
- 【回答框架 2】在 Webpack 打包时,import 语句会被转换为符合 CommonJS 或 ES 格式的模块包装代码,但 Webpack 会优先对 ES Module 进行静态分析,识别未使用的导出以消除死代码。
- 【回答框架 3】CommonJS 的 require 可以在条件语句或函数中动态调用,导致 Webpack 无法精确确定依赖,因此通常不会进行 Tree Shaking;而 import 语法是静态的,必须在模块顶层声明,使得依赖关系一目了然。
- 【回答框架 4】从模块导出对象来看,CommonJS 将 exports 作为一个对象整体暴露,而 ES Module 的导出是绑定关系的只读视图。Webpack 处理这两种模块时,会分别生成不同的运行时辅助函数(如 `__webpack_require__` 和 `__webpack_require__.n`)。
- 【关键点 1】import 是静态语法,require 是动态调用,这是两者核心区别。
- 【关键点 2】ES Module 支持 Tree Shaking,CommonJS 不支持。
- 【关键点 3】Webpack 通过静态分析 import 来优化打包体积。
- 【关键点 4】CommonJS 的 exports 对象是可变引用,ES Module 的导出是只读绑定。
- 【易错点 1】混淆 import 和 require 的执行时机,实际上 import 是编译时绑定,require 是运行时加载。
- 【易错点 2】误认为 Webpack 对所有模块都能 Tree Shaking,实际上仅对 ES Module 有效。