如何在 CommonJS 环境中正确导入并使用 ES 模块 random 库

9次阅读

如何在 CommonJS 环境中正确导入并使用 ES 模块 random 库

本文详解如何解决 `err_require_esm` 错误:将 `require(‘random’)` 改为动态 `import()`,并适配其 es 模块 api(如 `random.int()`),确保在 node.js commonjs 项目中正常调用随机数生成函数。

Node.js 从 v14 开始对 ES 模块(ESM)支持日益完善,而许多新发布的 npm 包(如 random)已默认发布为纯 ESM 格式(即仅含 .mjs 或 type: “module” 的 package.json)。当你在 CommonJS(.js 文件 + require())环境中直接使用 const random = require(‘random’) 时,Node.js 会抛出 ERR_REQUIRE_ESM 错误——因为 CommonJS 不允许同步 require() 一个 ES 模块。

✅ 正确解法是:改用动态 import()(它在 CommonJS 和 ESM 中均被支持),并注意该模块的导出方式已变更——它不再默认导出一个可直接调用的函数,而是导出一个命名对象,例如 random.int()、random.float() 等。

✅ 步骤一:替换 require() 为动态 import()

由于 import() 返回 Promise,你需用 await 调用(因此所在函数必须是 async):

// ✅ 正确:使用动态 import 并 await async function generateRandom() {   const random = await import('random');   const x = random.int(0, 20); // 注意:不是 random(0, 20)   console.log(x); // 例如:13   return x; }

⚠️ 注意:不能在模块顶层(top-level)直接 await import(…)(除非你启用了 Top-Level Await 且文件是 ESM)。若需在 CommonJS 入口(如 index.js)中立即使用,推荐封装为 async 函数或在 main 中调用。

✅ 步骤二:确保 random 包已安装且版本兼容

运行以下命令安装最新版(v4+ 为 ESM-only):

npm install random

验证安装后,检查 node_modules/random/package.json 是否包含 “type”: “module” 或导出字段(”exports”)指向 .mjs 文件——这确认它是 ESM 包。

✅ 步骤三:使用正确的 API(关键!)

原代码 random(0, 20) 是旧版(v3 及之前)CommonJS 风格的默认导出调用。新版 random(v4+)不提供默认导出函数,而是导出一个具名对象:

用途 正确写法
整数随机(含边界) random.int(min, max)
浮点随机(含边界) random.float(min, max)
随机布尔 random.bool()
随机元素(数组) random.pick(array)

示例完整可运行代码(index.js,CommonJS):

// index.js —— CommonJS 模块 async function main() {   try {     const random = await import('random');     const num = random.int(0, 20); // ✅ 正确:调用具名方法     console.log('Random integer:', num);   } catch (err) {console.error('Failed to import random:', err);   } }  main();

? 补充说明与替代方案

  • ❌ 不要尝试 require(‘random’).default 或 require(‘random’).int —— 它们不存在,会报 undefined。

  • ✅ 若你无法修改调用逻辑(坚持保留 random(0,20) 形式),可自行封装一层兼容函数:

    async function getRandom() {   const random = await import('random');   return (min, max) => random.int(min, max); }  // 使用:(async () => {const random = await getRandom();   console.log(random(0, 20)); // 现在可以这样写了 })();
  • ? 在 Express / Koa 等框架中,通常可在 路由 处理函数中 await import(),无需全局引入。

✅ 总结

问题原因 解决方式
require() 无法加载 ESM 包 改用 await import(‘random’)
误用旧版 API random(0,20) 改为 random.int(0,20)(查看 官方文档
同步调用需求 封装为 async 工具函数,或预加载后缓存实例

遵循以上步骤,即可彻底解决 ERR_REQUIRE_ESM 错误,并正确、安全地使用现代 random 库。

text=ZqhQzanResources