如何在Node.js脚本中同时使用require和import语法?
在同一Node.js文件中混用require和import的解决方案
核心原理
Node.js的ES模块(ESM)与CommonJS(CJS)是两套独立的模块系统,默认不允许在同一文件中直接混用静态import和require语法,但可以通过工具函数兼容或动态导入实现两种语法共存。
方案1:以ES模块(ESM)模式运行,兼容require
配置步骤
- 文件与package.json设置:
- 若使用
.js扩展名:在package.json中添加"type": "module" - 若使用
.mjs扩展名:无需修改package.json
- 若使用
- 在ESM中调用require:
Node.js提供了createRequire工具函数,可在ESM环境中生成CommonJS风格的require方法,代码示例:import { createRequire } from 'module'; const require = createRequire(import.meta.url); // 同时使用两种语法 import day from '@xkeshav/day'; const lodash = require('lodash'); console.log(day(), lodash.version);
方案2:以CommonJS(CJS)模式运行,兼容import
配置步骤
- 文件与package.json设置:
- 若使用
.js扩展名:确保package.json中没有"type": "module"(默认即为CJS模式) - 若使用
.cjs扩展名:无需修改package.json
- 若使用
- 在CJS中调用import:
CJS不支持静态import,需用动态import()(返回Promise)实现,代码示例:// 先用require加载CommonJS模块 const lodash = require('lodash'); // 动态导入ES模块,需用async/await处理异步逻辑 (async () => { const dayModule = await import('@xkeshav/day'); const day = dayModule.default; console.log(day(), lodash.version); })();
扩展名选择建议
- 优先用
.js配合package.json的"type"字段:项目统一模块风格时更清晰,全项目ESM就设"type": "module",全CJS则不配置该字段 - 特殊场景用
.mjs/.cjs:当单个文件需要与项目默认模块系统不同时使用,比如项目是CJS但某文件需用ESM,就用.mjs
关键说明
- 静态
import和require无法直接混用的原因:Node.js加载文件时会先确定模块类型(ESM或CJS),加载阶段会严格检查静态语法,因此两种静态语法不能共存。 - CJS中使用动态import()必须处理异步逻辑,这是与ESM中静态import的核心区别。
内容的提问来源于stack exchange,提问作者xkeshav
相关产品推荐
相关产品推荐

