CommonJS vs. ES Module:代码案例对比
在 JavaScript 中,模块化规范是程序员们不可或缺的重要环节。而在目前流行的两种模块化规范中,CommonJS 和 ES Module 是最为常用的。今天我们就来谈一谈这两种规范的异同点以及如何在代码中使用它们。
实现方式 | 导出语法 | 导入语法 | |
---|---|---|---|
CommonJS | 运行时动态加载 | module.exports 和 exports.funcName = func |
require() 方法 |
ES Module | 编译时分析依赖关系 | export default 和 export { func1, func2 } |
import 关键字 |
CommonJS
CommonJS 是 Node.js 最初提出的模块化规范,它主要是为了解决 JavaScript 在浏览器端缺少模块系统的问题。在 CommonJS 规范中,一个文件就是一个模块,每个模块都有一个独立的作用域,其他模块无法直接访问该作用域下的变量或函数。
导出
在 CommonJS 中,导出模块成员采用 module.exports
或 exports
。其中,module.exports
是真正的导出对象,而 exports
只是 module.exports
的一个引用。我们可以通过为 module.exports
赋值来导出多个成员,也可以通过为 exports
添加属性来导出单个成员。例如:
// 导出单个成员
exports.func = function () {};
// 导出多个成员
module.exports = {
func1: function () {},
func2: function () {},
};
导入
在 CommonJS 中,导入模块成员采用 require
。当我们需要在一个模块中使用其他模块的成员时,可以使用 require
方法将该模块引入。例如:
const moduleA = require('./moduleA');
function foo() {
return moduleA.func1();
}
ES Module
ES Module 是 ECMAScript 6 的一部分,它定义了 JavaScript 的官方模块化规范。它提供了更为简洁的语法以及更为强大的特性。在 ES Module 中,每个文件都是一个独立的模块,模块内部的变量和函数默认是私有的,需要使用 export
关键字来向外部暴露。
导出
在 ES Module 中,导出模块成员采用 export
关键字,可以使用 export default
导出默认成员。例如:
// 导出单个成员
export function func() {}
// 导出多个成员
export const obj = {};
export function func1() {}
导入
在 ES Module 中,导入模块成员采用 import
关键字。当我们需要在一个模块中使用其他模块的成员时,可以使用 import
关键字将该模块引入。例如:
import { func1 } from './moduleA.js';
import obj from './moduleB.js';
function foo() {
return func1();
}
需要注意的是,在 ES Module 中,引入的模块路径必须带有 .js
后缀名,并且相对路径和绝对路径需要明确指定。
区别对比
CommonJS 和 ES Module 的实现方式不同
CommonJS 主要是为服务端设计的,通过 require()
方法实现模块导入。可以在运行时动态加载代码,但是无法在编译时分析出代码依赖关系。
ES Module 则采用了静态导入机制,可以在编译时分析出代码的依赖关系。同时,ES Module 支持动态导入,通过 import()
方法在运行时动态加载代码。
CommonJS 和 ES Module 导出语法不同
在 CommonJS 中,可以将多个成员合并到一个对象中进行导出,也可以通过 exports.funcName = func
的方式导出单个成员。
在 ES Module 中,每个模块只能有一个默认导出,可以通过 export default
关键字实现。也可以通过 export { func1, func2 }
的方式导出多个成员。
CommonJS 和 ES Module 导入语法不同
在 CommonJS 中,通过 require()
方法导入模块,它返回的是一个对象。
在 ES Module 中,可以使用 import { func1, func2 } from './module.js'
的方式导入具体的成员,也可以使用 import * as module from './module.js'
的方式导入整个模块。
代码案例
接下来,我将展示一些在 CommonJS 和 ES Module 中的导入导出语法例子,以便于更好地理解它们的差异:
CommonJS
// moduleA.js
const func1 = function () {};
const func2 = function () {};
// 导出多个成员
module.exports = {
func1,
func2,
};
// moduleB.js
const func3 = function () {};
// 导出单个成员
exports.func3 = func3;
// app.js
const moduleA = require('./moduleA');
const { func3 } = require('./moduleB');
function foo() {
return moduleA.func1() + moduleA.func2() + func3();
}
ES Module
// moduleA.js
export const func1 = function () {};
export const func2 = function () {};
// moduleB.js
export default function func3() {}
// app.js
import { func1, func2 } from './moduleA.js';
import func3 from './moduleB.js';
function foo() {
return func1() + func2() + func3();
}
总结
CommonJS 和 ES Module 都是当前 JavaScript 中流行的模块化规范,在实际应用中,需要根据项目特点来选择合适的模块化规范。CommonJS 在 Node.js 的使用上非常方便,而且兼容性好;ES Module 则支持更为灵活的语法,可以提高编译效率。
总之,在选择模块化规范时,要综合考虑项目场景、开发需求以及代码架构的整体规划。对于初学者来说,建议先熟悉 CommonJS 规范,等理解了其原理和应用后再去尝试 ES Module 规范,这样才能更好地掌握 JavaScript 的模块化编程技能。
原文链接:https://juejin.cn/post/7238442926335475767 作者:半生瓜i