当前位置: 首页 > news >正文

Node.js 模块化规范详解

在 Node.js 中,模块化是开发应用程序的核心概念,它使得代码可以按照功能模块进行分割,易于维护、复用和扩展。Node.js 支持两种模块化规范:

  • CommonJS(CJS):这是 Node.js 最初使用的模块化规范。

  • ECMAScript Modules(ESM):这是现代 JavaScript 的官方模块化规范,自 ECMAScript 2015(ES6)引入。

1. CommonJS 模块化规范

CommonJS 是 Node.js 早期就支持的模块化标准,允许在服务端使用模块。在 CommonJS 中,每个文件都被视为一个独立的模块。你可以通过 module.exports 导出模块内容,并使用 require() 函数引入模块。

1.1. CommonJS 基本用法

  • 导出模块:使用 module.exports 或 exports。

  • 引入模块:使用 require()。

定义模块:

// math.js - 定义模块
function add(a, b) {return a + b;
}function subtract(a, b) {return a - b;
}// 使用 module.exports 导出模块
module.exports = {add,subtract,
};// 或者也可以使用 exports(两者作用相同)
exports.add = add;
exports.subtract = subtract;

引入模块:

// main.js - 引入并使用模块
const math = require('./math');console.log(math.add(5, 3));  // 输出:8
console.log(math.subtract(5, 3));  // 输出:2

1.2. CommonJS 特点

  • 同步加载:require() 是同步的,这意味着模块会在需要时同步加载。这在服务端是可以接受的,但在浏览器中不够高效。

  • 模块缓存:加载的模块会被缓存,因此多次 require() 同一个模块时,模块只会被加载一次。

2. ECMAScript Modules 规范

随着 JavaScript 语言的发展,ECMAScript Modules(ESM)被引入,成为 JavaScript 官方标准的模块系统。Node.js 从版本 12.17 开始支持 ESM,Node.js 通过引入 .mjs 文件扩展名和 package.json 中的 "type": "module" 字段来实现对 ESM 的支持。

2.1. ECMAScript Modules 基本用法

  • 导出模块:使用 export 关键字。

  • 引入模块:使用 import 关键字。

定义模块:

// math.mjs - 定义模块
export function add(a, b) {return a + b;
}export function subtract(a, b) {return a - b;
}

导入模块:

// main.mjs - 引入并使用模块
import { add, subtract } from './math.mjs';console.log(add(5, 3));  // 输出:8
console.log(subtract(5, 3));  // 输出:2

2.2. ESM 特点

  • 静态解析:ESM 是静态的,这意味着在代码编译时就能确定模块的依赖关系(相较于 CommonJS 的动态加载)。

  • 异步加载:import 支持异步加载,这在浏览器中更高效,特别是当你需要懒加载模块时。

  • 严格模式:所有的 ECMAScript 模块都默认处于严格模式("use strict")。

  • 不允许动态导入和导出:ESM 不支持像 CommonJS 那样的动态 require,必须在顶层进行 import/export。

3. 文件后缀与模块加载规则

3.1. CommonJS 文件后缀

对于 CommonJS 模块,文件通常使用 .js 后缀。如果你在 Node.js 中编写 CommonJS 模块,直接使用 .js 文件即可。

3.2. ECMAScript 模块的文件后缀

在 Node.js 中,可以通过以下两种方式启用 ESM:

  • 使用 .mjs 文件后缀:如果文件扩展名是 .mjs,Node.js 会将其视为 ESM。

  • 配置 package.json:在项目的 package.json 中设置 "type": "module",这样即使文件是 .js 后缀,Node.js 也会将其作为 ESM 处理。

3.3. 如何区分 CommonJS 和 ESM

Node.js 根据以下规则来确定模块系统:

  • CommonJS:默认情况下,Node.js 中所有 .js 文件都被视为 CommonJS 模块,除非另有指定。

  • ESM:当你使用 .mjs 扩展名,或者在 package.json 中指定 "type": "module",所有的 .js 文件都会被视为 ESM 模块。

4. require 和 import 互操作性

尽管 Node.js 支持 CommonJS 和 ESM 两种规范,但两者在一起使用时需要注意一些限制:

4.1. 从 CommonJS 中引入 ESM

从 CommonJS 文件中引入 ESM 模块是有一定限制的。require() 无法直接加载 ESM 模块,必须使用 import() 函数(它是一个异步函数)。

// 在 CommonJS 模块中动态引入 ESM 模块
(async () => {const math = await import('./math.mjs');console.log(math.add(5, 3));
})();

4.2. 从 ESM 中引入 CommonJS

ESM 模块可以直接通过 import 引入 CommonJS 模块,因为 Node.js 会将 CommonJS 模块包装成 ESM 格式以供使用。

// 在 ESM 中引入 CommonJS 模块
import math from './math.js';  // 假设 math.js 是一个 CommonJS 模块
console.log(math.add(5, 3));

5. 选择 CommonJS 还是 ESM?

在实际开发中,选择使用 CommonJS 还是 ESM 取决于几个因素:

  • 兼容性:如果你要支持旧的 Node.js 版本(12 之前)或使用大量依赖的第三方库(特别是历史遗留的),CommonJS 可能更合适。

  • 未来发展:ESM 是 JavaScript 官方标准,未来会有更多的支持,因此如果是新项目,推荐使用 ESM。

  • 生态系统:目前 Node.js 生态中的大多数库仍然使用 CommonJS,但越来越多的库开始迁移到 ESM。


文章转载自:

http://B9MI79cj.hkshy.cn
http://j5s6mx7y.hkshy.cn
http://Z9elZwPO.hkshy.cn
http://s3aEXD2N.hkshy.cn
http://WrIT4H8x.hkshy.cn
http://42AnZNkW.hkshy.cn
http://qvxQX4wk.hkshy.cn
http://gb3gtawJ.hkshy.cn
http://pnNE9kNA.hkshy.cn
http://3UeRgSCQ.hkshy.cn
http://jIO9vTP5.hkshy.cn
http://DDuNbvtX.hkshy.cn
http://XuMqcsWj.hkshy.cn
http://TthoXygx.hkshy.cn
http://kc57xn7U.hkshy.cn
http://YEBrEoki.hkshy.cn
http://EbCZxlMq.hkshy.cn
http://VgZJ1xg6.hkshy.cn
http://z5yQDFEx.hkshy.cn
http://T8OxILUQ.hkshy.cn
http://NyWvyzOQ.hkshy.cn
http://fHFXIM9o.hkshy.cn
http://Bgo2BGxd.hkshy.cn
http://1F5vt6RA.hkshy.cn
http://sOeV9WbZ.hkshy.cn
http://JEGcsITE.hkshy.cn
http://QfyoUCQe.hkshy.cn
http://8ZHZKQHj.hkshy.cn
http://lK3VpFaG.hkshy.cn
http://ftUfYkS9.hkshy.cn
http://www.dtcms.com/a/377879.html

相关文章:

  • Neo4j--登录及简单操作
  • 使用nvm安装Node.js18以下报错解决方案——The system cannot find the file specified.
  • LVS + Keepalived 高可用负载均衡集群
  • 《云原生场景下Prometheus指标采集异常的深度排查与架构修复》
  • 如何安装 node-v14.16.1-x64.msi?Node.js 14.16.1 64位MSI安装详细步骤
  • React 基础
  • 自动化SSL证书管理:应对域名SSL证书更新焦虑
  • 跨平台快速上手:Couchbase 安装与使用指南
  • 【译】Visual Studio 八月更新已发布 —— 更智能的人工智能、更出色的调试功能以及更多控制权
  • python+selenium+PO模式
  • Excel表格如何制作?【图文详解】表格Excel制作教程?电脑Excel表格制作?
  • 【基于CNN的57类交通标志识别系统】
  • 【深度学习新浪潮】Nano Banana(Gemini 2.5 Flash Image)技术解析与开发者实操指南
  • 【Qt开发】显示类控件(二)-> QLCDNumber
  • 三角孔径衍射误差难分析?OAS 软件深度仿真解难题
  • 鸿蒙Next Web组件生命周期详解:从加载到销毁的全流程掌控
  • 【从0开始学习Java | 第17篇】集合(中-Set部分)
  • 【AI指导】Python实现prophet模型的业绩预测
  • RPA-4.0.0.0_SAAS新版本已上线,Edge扩展自动安装,快速实现RPA流程自动化
  • Server 13 ,CentOS 上使用 Nginx 部署多个前端项目完整指南( 支持多端口与脚本自动化 )
  • Java后端测试
  • Skywork-OR1:昆仑万维开源的数学代码推理系列模型
  • 【Linux】基本指令 · 上
  • OBS插件详细教程:OBS美颜插件下载,OBS美颜插件怎么用?
  • 如何在 Spring Boot 中指定不同的配置文件?
  • spring boot 拦截器增加语言信息
  • leedcode 算法刷题第三十二天
  • CentOS 7 下iscsi存储服务配置验证
  • 求解指定泛函的驻点所满足的偏微分方程及边界条件
  • 股指期货保证金一手需要多少钱?