NodeJS脚本拆分多文件:require与import兼容问题排查
解决Node.js模块语法混用的报错问题
你的问题核心是混用了CommonJS(require/exports)和ES模块(import/export)语法,Node.js对这两种模块机制的处理规则不同,导致接连报错。下面给两种彻底解决的方案,选一种统一使用即可:
方案一:全程使用CommonJS(适合习惯旧写法的场景)
- 删除
package.json里的"type": "module"配置,让Node.js默认按CommonJS处理所有文件 - 修改
myLib.js,把ES模块的import替换为CommonJS的require:
// myLib.js const camelCase = require('camelcase'); const myCamelCaseFn = (arg) => camelCase(arg); exports.myCamelCaseFn = myCamelCaseFn;
- 修正
main.js的require写法(之前的代码会把整个模块对象赋值给变量,无法直接调用函数):
// main.js // 解构出需要的函数 const { myCamelCaseFn } = require('./lib/myLib'); myCamelCaseFn("do something"); // 或者也可以这样写 // const myLib = require('./lib/myLib'); // myLib.myCamelCaseFn("do something");
方案二:全程使用ES模块(推荐的新写法)
- 确保
package.json里保留"type": "module",让Node.js把所有文件当作ES模块处理 - 修改
myLib.js,用ES模块的export语法替代exports:
// myLib.js import camelCase from 'camelcase'; // 导出单个函数 export const myCamelCaseFn = (arg) => camelCase(arg);
- 修改
main.js的import路径,ES模块必须指定完整文件名(包括.js后缀):
// main.js import { myCamelCaseFn } from './lib/myLib.js'; myCamelCaseFn("do something");
如果一定要用动态import,记得它返回Promise对象,必须用async/await或者.then()处理:
// main.js async function run() { const { myCamelCaseFn } = await import('./lib/myLib.js'); myCamelCaseFn("do something"); } run();
补充说明各个报错的原因:
cannot use import statement outside a module:未添加"type":"module"时,Node.js默认将文件视为CommonJS模块,不支持ES模块的import语法cannot find module lib/myLib:ES模块的import必须指定完整文件名(含.js),省略后缀会导致Node.js无法找到文件myCamelCaseFn is not function:动态import返回的是Promise对象,而非直接的函数,必须等待Promise完成后才能获取模块内容ReferenceError: exports is not defined in ES module scope:ES模块环境中不存在exports/module.exports对象,只能使用ES标准的export语法导出内容
内容的提问来源于stack exchange,提问作者Zoltan Hernyak
相关产品推荐
相关产品推荐

