ES6 模块和 CommonJS 模块是 JavaScript 中两种主要的模块化方案,它们在设计理念、语法、加载方式等方面有显著的区别。以下是它们的主要区别:
1. 语法
ES6 模块
- 使用
import
和export
关键字。 - 支持静态导入,允许在编译时解析模块依赖关系。
示例:
javascript
// myModule.js
export const myVariable = 42;
export function myFunction() {
console.log('Hello from myFunction');
}
// main.js
import { myVariable, myFunction } from './myModule.js';
CommonJS 模块
- 使用
require
导入模块,使用module.exports
导出模块。 - 模块是动态加载的,依赖关系在运行时解析。
示例:
javascript
// myModule.js
const myVariable = 42;
function myFunction() {
console.log('Hello from myFunction');
}
module.exports = { myVariable, myFunction };
// main.js
const myModule = require('./myModule');
2. 加载方式
ES6 模块
- 静态加载:在编译时解析所有的模块依赖关系,支持树摇优化(tree shaking),可以移除未使用的代码。
- 异步加载 :可以使用动态
import()
语法进行异步加载。
CommonJS 模块
- 动态加载:模块是在运行时加载的,支持条件加载和动态导入。
- 同步加载:通常用于服务器端,模块加载是同步的。
3. 作用域
ES6 模块
- 每个模块都有自己的作用域,模块内部的变量不会污染全局作用域。
- 默认情况下,模块中的变量是私有的,只有通过
export
导出的成员才能被外部访问。
CommonJS 模块
- 也有自己的作用域,使用
this
关键字指向模块的exports
对象。 - 模块内部的变量也不会污染全局作用域。
4. 导入和导出方式
ES6 模块
- 支持命名导出和默认导出。
- 可以导入多个命名导出,也可以导入默认导出。
javascript
// 默认导出
export default function myDefaultFunction() {
console.log('Default function');
}
// 导入默认导出
import myDefaultFunction from './myModule.js';
// 导入命名导出
import { myVariable } from './myModule.js';
CommonJS 模块
- 只有一个导出对象,通过
module.exports
导出。 - 导入时获取整个模块的导出对象。
javascript
// 导出
module.exports = {
myVariable,
myFunction,
};
// 导入
const myModule = require('./myModule');
const myVariable = myModule.myVariable;
5. 适用场景
ES6 模块
- 主要用于现代的浏览器和支持 ES6 的环境(如 Node.js 12 及以上)。
- 适合前端开发,支持模块的静态分析和优化。
CommonJS 模块
- 主要用于 Node.js 环境,广泛用于服务器端 JavaScript。
- 适合需要动态加载模块的场景。
6. 兼容性
ES6 模块
- 需要现代环境的支持,老旧的浏览器可能不支持。
- 可以通过构建工具(如 Babel)转换为其他模块格式。
CommonJS 模块
- Node.js 原生支持,兼容性好。
- 可以在浏览器中使用打包工具(如 Browserify)进行转换。
总结
ES6 模块和 CommonJS 模块在语法、加载方式、作用域和适用场景等方面有明显区别。ES6 模块支持静态分析和异步加载,更适合现代开发;