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

CommonJS项目导入ESM库遇ERR_REQUIRE_ESM错误,求解决方法

可以在CommonJS项目中导入ESM包吗?

可以,但不能使用常规的静态import或require(),因为Node.js会阻止CommonJS模块同步加载纯ESM包。以下是针对你的TypeScript CommonJS项目的可行解决方案:

方案1:使用动态import()(官方推荐)

Node.js允许所有CommonJS模块使用动态import()函数异步加载ESM包,这是最直接的解决方式。

具体实现

将原来的静态导入替换为异步动态导入,结合async/await处理:

// 替换静态导入:import { someFunc } from "esm-dependency";
async function initApp() {
  // 动态导入ESM依赖
  const esmDependency = await import("esm-dependency");
  // 注意:如果依赖使用默认导出,需要访问.default属性
  const { someFunc } = esmDependency;

  // 后续业务逻辑,比如启动Express服务
  const express = require("express");
  const app = express();

  app.get("/", (req, res) => {
    res.send(someFunc());
  });

  app.listen(3000, () => {
    console.log("Server running on port 3000");
  });
}

initApp();

TypeScript配置注意

确保tsconfig.json中以下配置正确:

{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES2017", // 需支持async/await特性
    "moduleResolution": "Node10",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

方案2:转译ESM依赖为CommonJS

如果动态导入的异步逻辑对你的项目结构不友好,可以通过构建工具将ESM依赖转译为CommonJS格式后再导入。

用esbuild批量转译

编写简单脚本,用esbuild把ESM依赖打包成CommonJS:

// build-deps.js
const esbuild = require('esbuild');

esbuild.build({
  entryPoints: ['node_modules/esm-dependency/index.js'],
  outfile: 'dist/esm-dependency.cjs',
  format: 'cjs',
  bundle: true,
}).catch(() => process.exit(1));

运行脚本后,直接导入转译后的文件:

const { someFunc } = require("./dist/esm-dependency.cjs");

注意事项

  • 这种方式需要维护转译脚本,依赖更新后需重新转译
  • 部分依赖可能包含无法转译的ESM特性,需测试验证

为什么你之前的方案没奏效?

  • Webpack相关方案仅适用于Webpack打包的项目,如果你的项目是用ts-node直接运行,该方案不适用
  • Babel-loader方案需要正确配置@babel/preset-env和@babel/plugin-syntax-dynamic-import,且需确保Babel处理了node_modules中的ESM依赖(默认Babel会忽略node_modules)

内容的提问来源于stack exchange,提问作者BSimpson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:52:13