You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js CommonJS模块中动态导入ESM模块(无需type:module/.mjs且支持纯ESM依赖)

在CommonJS中动态导入ESM模块(含依赖纯ESM的模块)

一、原生动态import的可行方案(无需修改package.json或扩展名)

你之前尝试的动态import其实能满足需求,核心是要正确使用异步逻辑:动态import()本身是异步的,在CommonJS模块里用它加载ESM模块,完全不需要配置"type":"module"或.mjs扩展名。之前的问题大概率是写法没到位,或者对模块导出的处理有误。

举个实际例子,假设要导入的ESM模块my-esm-module.js依赖node-fetch@3这类纯ESM包:

// 这是CommonJS模块(.js文件,package.json无type:module配置)
async function loadTargetEsm() {
  try {
    // 动态导入目标ESM模块
    const esmModule = await import('./my-esm-module.js');
    // 按需调用模块导出的内容,比如default导出
    esmModule.default.doSomething();
  } catch (err) {
    console.error('导入失败:', err);
  }
}

// 执行加载逻辑
loadTargetEsm();

注意要点:

  • 必须用await或.then()处理import()返回的Promise,不能同步调用
  • 目标ESM模块的依赖(比如node-fetch@3)会被Node.js原生ESM加载器自动解析,不需要额外配置
  • 确保目标ESM模块用标准ESM语法导出(export/export default)

如果是直接导入第三方纯ESM包(比如node-fetch@3),写法类似:

async function useNodeFetch() {
  const fetch = (await import('node-fetch')).default;
  const res = await fetch('https://example.com');
  console.log(await res.text());
}

二、关于esm npm包的问题

你提到的esm包确实能让CommonJS加载普通ESM,但它的底层是在CommonJS环境里模拟ESM运行逻辑,和Node.js原生ESM加载器的解析规则有差异,对依赖纯ESM包的模块支持很差——这是它的设计局限,目前没有官方配置能解决这个问题。现在Node.js原生已经完善了动态import支持,完全没必要再依赖esm包。

三、避坑提醒

  • 绝对不能用require()加载ESM模块,这会直接抛出错误,必须用动态import()
  • 如果项目里有大量ESM模块需要在CommonJS环境中调用,保持入口为CommonJS,通过动态import批量加载即可,不用修改整个项目的模块类型

内容的提问来源于stack exchange,提问作者norma.moore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:13:08