CommonJS 模块和 ES 模块是 JavaScript 中两种不同的模块系统,它们在语法、执行时机、动态导入等方面存在显著差异。
1. 语法:
-
CommonJS: 使用
require()
同步加载模块,使用module.exports
或exports
导出模块成员。// 模块A const add = (a, b) => a + b; module.exports = { add }; // 模块B const { add } = require('./moduleA');
-
ES 模块: 使用
import
语句导入模块,使用export
语句导出模块成员。// 模块A export const add = (a, b) => a + b; // 模块B import { add } from './moduleA';
2. 执行时机:
-
CommonJS: 模块加载和执行是同步的。
require()
会阻塞代码执行,直到模块加载完成。这意味着 CommonJS 模块的执行顺序与它们在代码中出现的顺序一致。 -
ES 模块: 模块加载和执行是异步的。
import
语句不会阻塞代码执行,浏览器会在后台加载模块。ES 模块的执行顺序取决于模块之间的依赖关系和浏览器的加载策略。 所有导入的模块都会在当前模块的顶层作用域之前执行。
3. 动态导入:
-
CommonJS: 支持动态导入,但需要使用
require()
,并且是同步的。const modulePath = './module' + someVariable; const myModule = require(modulePath);
-
ES 模块: 支持动态导入,使用
import()
函数,并且是异步的,返回一个 Promise。const modulePath = './module' + someVariable; import(modulePath).then(module => { // 使用 module });
4. 顶层作用域:
-
CommonJS: 每个模块都有自己的顶层作用域。在一个模块中定义的变量、函数等不会污染全局作用域,也不会被其他模块直接访问,除非显式导出。
-
ES 模块: ES 模块的顶层作用域是共享的。这意味着在 ES 模块顶层声明的变量、函数等,在其他导入该模块的地方是可见的,类似于全局变量。 但是,ES 模块的设计理念仍然鼓励尽可能地使用
export
和import
来管理模块之间的依赖关系,而不是依赖共享的顶层作用域。
5. 兼容性:
-
CommonJS: 主要用于 Node.js 环境,浏览器端需要使用构建工具(如 Webpack、Browserify)进行转换。
-
ES 模块: 是 JavaScript 的标准模块系统,现代浏览器都原生支持 ES 模块。
总结:
特性 | CommonJS | ES 模块 |
---|---|---|
语法 | require() , module.exports , exports |
import , export |
执行时机 | 同步 | 异步 |
动态导入 | require() (同步) |
import() (异步) |
顶层作用域 | 模块私有 | 模块共享 (但建议使用 export /import ) |
兼容性 | Node.js | 现代浏览器 |
选择哪种模块系统取决于你的项目环境和需求。 对于新的前端项目,推荐使用 ES 模块,因为它更现代化,性能更好,并且是 JavaScript 的标准。 对于 Node.js 项目,CommonJS 仍然是主流,但 ES 模块的支持也越来越好。 许多项目会混合使用两种模块系统,尤其是在过渡阶段。
标签:commonJS,作用域,CommonJS,module,模块,import,ES From: https://www.cnblogs.com/ai888/p/18583380