编辑
2023-08-05
Nodejs
00
请注意,本文编写于 474 天前,最后修改于 474 天前,其中某些信息可能已经过时。

目录

CommonJS规范
姿势一:module.exports集中导出
姿势二:exports逐个导出
姿势三:直接赋值给module.exports
ESM规范
姿势一:export命名导出
姿势二:export default默认导出
姿势三:export + export default 混合导出
姿势四:重新导出
姿势五:全部导入
异同点对比
加载方式
静态分析
动态导入
应用场景
注意事项
总结

在现代的JavaScript开发中,模块化是一个至关重要的概念,它有助于将代码拆分为独立的、可维护的部分,使开发过程更加高效和可靠。在JavaScript社区中,有两种主要的模块化规范:CommonJS(通用模块化规范)和ESMECMAScript模块)规范。本文将深入探讨这两种规范的异同点、应用场景以及注意事项。

CommonJS规范

CommonJS是一种早期引入的模块化规范,最初用于服务器端JavaScript(如Nodejs)。它的主要特点包括:

  • 同步加载模块: CommonJS模块是同步加载的,即在需要的地方使用require函数加载模块,并立即获取其导出内容。
  • 导出方式: 使用module.exports导出模块内容,或者通过给exports对象添加属性来导出单个成员

姿势一:module.exports集中导出

js
// 导出 // utils.js module.exports = { add: (a, b) => a + b, subtract: (a, b) => a - b }; // 导入 // app.js const { add, subtract } = require('./utils'); console.log(add(5, 3)); // 输出: 8 console.log(subtract(5, 3)); // 输出: 2

姿势二:exports逐个导出

js
// 导出 // utils.js exports.add = (a, b) => a + b; exports.subtract = (a, b) => a - b; // 导入 // app.js const { add, subtract } = require('./utils'); console.log(add(5, 3)); // 输出: 8 console.log(subtract(5, 3)); // 输出: 2

姿势三:直接赋值给module.exports

js
// 导出 // utils.js module.exports = (a, b) => a + b; // 导入 // app.js const add = require('./utils'); console.log(add(5, 3)); // 输出: 8

ESM规范

ESMECMAScript官方引入的模块化规范,它在现代浏览器和Nodejs中都得到了广泛支持。它的主要特点包括:

  • 异步加载模块: ESM模块是异步加载的,模块需要使用import语句加载,可以在运行时动态加载模块。
  • 导出方式: 使用export关键字导出模块内容,可以导出多个成员,也可以起别名。

姿势一:export命名导出

使用export关键字,可以命名导出一个或多个成员,这些成员在导入时需要使用相应的名称来访问。

js
// 导出 // utils.js export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } // 导入 // app.js import { add, subtract } from './utils'; console.log(add(5, 3)); // 输出: 8 console.log(subtract(5, 3)); // 输出: 2

姿势二:export default默认导出

使用export default关键字,可以导出一个默认成员,一个模块只能有一个默认导出。

js
// 导出 // utils.js const add = (a, b) => a + b; export default add; // 导入 import add from './utils'; console.log(add(5, 3)); // 输出: 8

在导入时,可以自定义默认导出成员的名称:

js
// 导入并重命名 import myAddFunction from './utils'; console.log(myAddFunction(5, 3)); // 输出: 8

姿势三:export + export default 混合导出

在一个模块中,既可以有命名导出,又可以有默认导出。

js
// 导出 // utils.js export function add(a, b) { return a + b; } function subtract(a, b) { return a - b; } export default subtract; // 导入 // app.js import subtract, { add } from './utils'; console.log(add(5, 3)); // 输出: 8 console.log(subtract(5, 3)); // 输出: 2

姿势四:重新导出

可以在一个模块中重新导出另一个模块的成员,方便从一个中心模块导出所有需要的内容。

js
// 导出一 // mathUtils.js export function add(a, b) { return a + b; } // 导出二 // utils.js export function subtract(a, b) { return a - b; } export function multiply(a, b) { return a * b; } // 引入后重新集中导出 // main.js export { add } from './mathUtils'; export { subtract, multiply } from './utils'; // 导入 // app.js import { add, subtract, multiply } from './main'; console.log(add(5, 3)); // 输出: 8 console.log(subtract(5, 3)); // 输出: 2 console.log(multiply(5, 3)); // 输出: 15

姿势五:全部导入

使用import * as <alias>语法,可以将一个模块的所有导出成员导入为一个对象。

js
// 导出 // utils.js export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } // 导入 // app.js import * as math from './utils'; console.log(math.add(5, 3)); // 输出: 8 console.log(math.subtract(5, 3)); // 输出: 2

这些是ESM规范中常见的导出方式,通过灵活运用它们,可以更好地组织和管理模块化的JavaScript代码。

异同点对比

加载方式

  • CommonJS使用同步加载模块,适合服务器端,但在浏览器中可能会造成阻塞。
  • ESM使用异步加载模块,更适合浏览器环境,可以提高性能。

静态分析

  • ESM可以在静态分析时确定模块依赖关系,这使得一些优化和工具更易实现。
  • CommonJS在运行时才能确定依赖,限制了某些优化的可能性。

动态导入

  • ESM允许使用import()函数在运行时动态加载模块,以支持按需加载。
  • CommonJS没有原生的动态导入方式,尽管在Nodejs中可以使用实验性的import()函数。

应用场景

  • CommonJS适用于服务器端应用,特别是在Nodejs环境中,可以方便地管理模块依赖。
  • ESM适用于浏览器和现代Nodejs应用,尤其在前端项目中,可以利用浏览器的异步加载能力

注意事项

  • 当在Nodejs中使用ESM规范时,需要在脚本文件中使用.mjs扩展名,并在package.json中设置"type": "module"
  • ESM中的模块路径解析相对于当前文件,而CommonJS中相对于包含模块的目录。
  • ESM中的导入和导出是静态的,不能根据条件进行导入或导出,而CommonJS可以在运行时根据条件加载模块。

总结

CommonJSESM规范各有优势,选择取决于应用的环境和需求。

Nodejs环境中,可以根据项目需求选择使用哪种规范,而在现代的浏览器环境中,ESM规范更加适用。

熟悉这两种规范的异同以及各自的应用场景,将有助于开发者更好地进行模块化开发并提高代码质量和可维护性。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:CreatorRay

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!