
本文详解如何解决 `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 库。










