CommonJS模块导出函数后导入为对象,调用报‘不是函数’错误排查
以下是几种常见的原因及排查方向:
循环依赖导致的未完全初始化
如果你的CRUD模块与collectionWatch模块存在互相require的情况,Node.js的模块加载机制会在其中一个模块未完成初始化时就返回导出对象,此时拿到的可能是空对象。比如CRUD模块导入了collectionWatch,而collectionWatch又在内部导入了CRUD模块,就会触发这种加载异常。
排查方式:打印模块加载顺序,或检查两个模块的导入关系,移除不必要的循环依赖。导入/导出语法不匹配
检查CRUD模块的导入写法:- 如果
collectionWatch是用CommonJS语法module.exports = watchCollection导出的单个函数,而CRUD模块用了解构导入(比如const { watchCollection } = require('./collectionWatch')),就会因为找不到同名导出项而得到undefined,看起来像空对象。正确的写法应该是const watchCollection = require('./collectionWatch')。 - 反之,如果混用了ES模块的
import语法导入CommonJS模块,也可能出现解析错误。
- 如果
文件路径错误
CRUD模块中require的路径是否指向了错误的文件?比如相对路径层级错误(多写/少写了../),导致导入了一个不存在的空模块或同名的其他文件。可以在CRUD模块中执行console.log(require.resolve('./collectionWatch')),查看实际加载的文件路径是否正确。异步初始化导致导出未赋值
如果collectionWatch模块的导出依赖于异步操作(比如等待Mongoose连接完成后再赋值module.exports),而CRUD模块在异步操作完成前就同步导入了该模块,此时拿到的导出对象还未被赋值,会是空对象。
排查方式:检查collectionWatch模块的代码逻辑,确保导出操作是同步完成的,或者将初始化逻辑改为同步,或通过回调/Promise暴露函数。模块缓存异常
若之前collectionWatch模块加载时出现过错误,Node.js的模块缓存可能会保留一个不完整的导出对象。可以尝试重启Node.js服务清空模块缓存,或删除项目中的缓存目录(如node_modules/.cache)后重新运行。
内容的提问来源于stack exchange,提问作者ISAE

