在 ESM 中引入 CommonJS 模块

简介

随着越来越多的 Node.js 项目采用 ESM 作为模块系统,一些较旧的 CommonJS 模块依然被广泛使用。由于这两者的模块系统存在一些差异,我们可能会面临引入 CommonJS 模块到 ESM 项目中的挑战。

这种兼容性问题主要表现为:

  • ESM 模块系统使用 import 和 export,而 CommonJS 使用 require 和 module.exports。
  • Node.js 对文件扩展名(如 .js, .mjs, .cjs)的处理方式不同,可能会导致加载错误。

在 ESM 中引入 CommonJS 模块的几种方式

方法 1:使用 .cjs 后缀和 require()(同步加载)

这是最推荐的方式,它让你明确指定文件是 CommonJS 模块,并允许你使用同步的 require() 来导入模块。

步骤:

  1. 确保 CommonJS 模块使用 .cjs 后缀。
  2. 使用 createRequire 方法来引入 CommonJS 模块。
javascript 复制代码
// cjs-file.cjs
module.exports = {
  sayHi(name) {
    console.log(`Hi, ${name} from CommonJS`);
  }
};
javascript 复制代码
// esm-file.js
import { createRequire } from 'module';
const require = createRequire(import.meta.url);

const cjs = require('./cjs-file.cjs');
cjs.sayHi('Alice');

优点:

  • 同步加载,代码简单直观。
  • 兼容性好,适用于大多数 Node.js 项目。

方法 2:使用动态 import()(异步加载)

当你不能或不想使用 .cjs 后缀时,可以使用动态 import() 来加载 CommonJS 模块。由于 import() 是异步的,你需要使用 await 或 .then() 来处理加载。

dart 复制代码
// esm-file.js
const cjsModule = await import('./cjs-file.js');  // 动态导入
cjsModule.default.sayHi('Alice');

优点:

  • 灵活性高,可以按需加载模块。
  • 不要求模块使用 .cjs 后缀。

缺点:

  • 异步加载,代码稍显复杂。
  • 需要使用 default 属性来访问 CommonJS 导出的内容。
相关推荐
濮水大叔38 分钟前
Cabloy全栈框架的两个SSR入口:Vona集成式SSR vs Zova独立式SSR
typescript·node.js·全栈
怕浪猫1 小时前
DeepSeek Harness 系列图解
面试·前端框架·node.js
百万蹄蹄向前冲1 小时前
双端同步!云服务器装最新Node.js v26.10全过程追踪
服务器·人工智能·node.js
前端snow1 小时前
ai agent--- 后端概念补充:Docker Compose、ElasticSearch、IK、BM25等
node.js
EdgeEcho1 小时前
Node 里那个"只解第一帧"的坑,我用 172 行代码绕过去了
node.js
光影少年1 小时前
Redis + Node 如何支撑百万级并发
redis·后端·node.js
半个落月1 小时前
从“等待整段答案”到边生成边展示:大模型流式输出与 SSE 实战(上)
langchain·node.js
百万蹄蹄向前冲1 小时前
一句话生成Node.js学习官网秒发布上线
前端·后端·node.js
半个落月1 小时前
让大模型稳定返回可用数据:Output Parser、Zod 与 Tool Calling(下)
langchain·node.js
风尘小子6 天前
node.js系列:process配置
前端·node.js