CommonJS项目通过require引入nanoid报ERR_REQUIRE_ESM如何解决
问题原因
你碰到的两类报错本质原因是Nanoid 4.0及以上版本不再提供CommonJS规范的构建产物,仅支持ES Module形式引入,直接在CommonJS环境用require()加载会触发ERR_REQUIRE_ESM错误;而直接写import语句要么因为Node.js默认把.js文件当CommonJS解析报语法错,要么被Babel转译成require()后又触发ESM加载错误。
可落地方案
方案1:安装兼容CommonJS的Nanoid 3.x版本(适配成本最低,推荐)
这个版本原生支持require()引入,不需要修改项目模块配置,也不会和Babel转译逻辑冲突:
- 先卸载当前不兼容的版本
npm uninstall nanoid
- 安装3.x系列的最新稳定版
npm install nanoid@3.3.7
- 业务代码里按需求生成6位纯字母数字编码即可,注意不要直接调用默认的
nanoid()(默认会生成包含_、-的21位字符串),要用自定义字典方法:
const { customAlphabet } = require('nanoid'); // 字符集按需调整,这里是纯数字+大小写字母,如果要剔除易混淆的0/O/1/l可以自行从字符串里删掉 const generate6BitId = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 6); // 调用即可拿到符合要求的编码 const id = generate6BitId();
方案2:保留当前高版本Nanoid,用动态import引入
如果不想降级版本,可以用CommonJS环境原生支持的异步动态import()方法加载ESM模块,注意加载逻辑是异步的:
// 项目启动阶段提前初始化生成器 let generate6BitId; async function initIdGenerator() { if (generate6BitId) return generate6BitId; const { customAlphabet } = await import('nanoid'); generate6BitId = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 6); return generate6BitId; } // 业务调用时先确保初始化完成 async function getBizId() { const generator = await initIdGenerator(); return generator(); }
方案3:调整项目构建配置适配ESM
如果项目后续计划整体迁移到ESM规范,可以保留package.json里的"type": "module"配置,同时修改Babel规则,不要把Nanoid的import语句转译成require,不过这个方案需要调整现有项目的模块兼容逻辑,适配成本较高,不推荐为了单个库做这类改动。
提示:6位字母数字组合的总熵值是62^6≈568亿,正常业务场景下碰撞概率极低,如果你的业务调用量特别大,可以加一层数据库/缓存的唯一校验,彻底避免重复。
内容的提问来源于stack exchange,提问作者mohammad shahab
相关产品推荐
相关产品推荐

