ES Modules(ECMAScript Modules)和 CommonJS 的区别
1. 导入和导出语法差异:
-
ES Modules 使用
import
和export
语法来导入和导出模块。例如:// 导入 import { foo } from './module.js'; // 导出 export function bar() { // 函数体 } 请注意:在ES Modules,export {xx,xx}这种不是导出一个对象,而是固定的写法,而import {xx,xx} from 'xx'也不是在结构,他也是一个固定的写法
-
CommonJS 使用
require()
函数来导入模块,使用module.exports
或exports
对象来导出模块。例如:// 导入 const { foo } = require('./module'); // 导出 exports.bar = function() { // 函数体 }
2. 加载时机和方式:
- ES Modules:在编译时加载模块,模块加载是异步的,模块文件的依赖关系在静态分析阶段就确定了。
- CommonJS:在运行时加载模块,模块加载是同步的,模块文件的依赖关系是动态计算的。
3. 变量作用域:
ES Modules 模块是在严格模式下执行的,并且每个模块都有自己的顶层作用域,模块内部的变量默认不会被全局共享。
CommonJS 模块不会使用严格模式,它们的导入和导出是基于对象引用,所以可以共享模块内部的变量。
4. 动态导入:
-
ES Modules 支持动态导入(即在运行时根据条件导入模块)。例如,也就是他会延迟执行脚本,会等页面加载完毕之后再执行
const moduleSpecifier = './module.js'; import(moduleSpecifier).then(module => { // 使用模块 });
-
CommonJS 不支持动态导入,因为它是在运行时同步加载模块的。
5. 浏览器支持:
ES Modules 是 ECMAScript 的官方标准,现代浏览器广泛支持。
CommonJS 最初是 Node.js 的模块系统,主要用于服务器端开发,不适用于浏览器环境。
6.ES Modules可以引入CommonJS 导出的内容
但是CommonJS导出的成员在ES Modules中去引入的话,只能够使用默认的成员引入,也就是default的形式
在node的环境中,不允许CommonJS去引入ES Modules中的内容
比如commonJs可以打印的require或者module这些内容,在esModules中其实也是无法使用的
总结:
- ES Modules 更适合现代 JavaScript 开发,支持静态分析、异步加载、严格模式等特性,适用于浏览器和 Node.js 环境。
- CommonJS 适合于 Node.js 环境中的模块化开发,模块加载是同步的,变量共享比较方便。