Node.js中ES模块import/require使用报错问题求助
Node.js CommonJS与ES模块兼容问题解决办法
问题场景
- 原本用
require()加载文件和模块一切正常,现在频繁报错:Error [ERR_REQUIRE_ESM]: require() of ES Module ./lib/departments.cjs not supported, Instead change the require of inquirer.js in ./lib/departments.cjs to a dynamic import() which is available in all CommonJS modules.
- 换成
import语法后,又出现新错误:SyntaxError: Cannot use import statement outside a module
- 已在
package.json中添加"type": "module",但问题未解决,当前package.json内容如下:{ "name": "", "version": "1.0.0", "description": "", "main": "server.js", "directories": { "lib": "lib" }, "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node server.js" }, "repository": { "type": "git", "url": "git+https://.git" }, "author": "", "license": "MIT", "bugs": { "url": "https://issues" }, "homepage": "https://#readme", "dependencies": { "console.table": "^0.10.0", "dotenv": "^16.0.2", "express": "^4.18.1", "inquirer": "^9.1.1", "mysql2": "^2.3.3", "node-fetch": "^2.6.7" } }
解决方案
方案1:继续使用CommonJS规范
- 删除
package.json里的"type": "module"字段,让项目默认使用CommonJS - 针对inquirer这类纯ES模块依赖,改用**动态import()**替代
require(),修改./lib/departments.cjs示例:// 替换原来的 const inquirer = require('inquirer'); async function initInquirer() { const { default: inquirer } = await import('inquirer'); return inquirer; } // 调用异步函数使用inquirer async function runApp() { const inquirer = await initInquirer(); // 这里写你的inquirer逻辑 } runApp(); - 自定义文件后缀可以保持
.js(默认CommonJS),或者显式用.cjs区分
方案2:彻底切换到ES模块规范
- 确认
package.json中"type": "module"的位置没问题(你的配置里位置正确,属于顶层字段) - 把所有文件里的
require()全换成import语法:- 第三方依赖:
import inquirer from 'inquirer'; - 自定义模块:必须加完整后缀,比如
import departments from './lib/departments.js';(不能省略.js)
- 第三方依赖:
- 依赖兼容性调整:
node-fetch@2.x是CommonJS模块,在ES模块里可以直接导入,如果有问题就升级到node-fetch@3.x(纯ES模块)- 其他依赖如
mysql2、dotenv都支持ES模块导入
- 确保Node.js版本在14.13.0以上,这个版本开始完整支持ES模块
核心注意事项
- 同一项目里别混用
require()和import,保持规范统一 - 用ES模块时,自定义模块导入必须带完整文件后缀
- 纯ES模块依赖(比如inquirer@9.x)不能用
require()直接加载,要么用动态import,要么全项目转ES模块
内容的提问来源于stack exchange,提问作者dhuw
相关产品推荐
相关产品推荐

