Node+Webpack环境下Sequelize无法找到模型模块的优化修复问询
我明白你遇到的这个路径问题有多头疼——Webpack打包后Sequelize模型加载路径直接跑偏,明明模型在src/models目录,却跑到bin目录下去找不存在的文件了。咱们先拆解问题根源,再给出几个靠谱的解决方案。
问题根源
你看到的报错Cannot find module '/Library/WebServer/Documents/private/my-project/bin/src/models/currency.js',核心原因是Webpack对__dirname的处理行为:
- 你当前的Webpack配置里设置了
node: { __dirname: true },这会让Webpack把源码中的__dirname替换成打包后文件的所在目录(也就是bin/目录)。 - Sequelize自动生成的
src/models/index.js里,原本用path.join(__dirname, file)来加载同目录下的模型,但打包后__dirname指向了bin/src/models(实际不存在),自然找不到正确的模型文件。
最优解决方案:修改Webpack的__dirname配置
这是最干净的解决方式,不需要改动业务代码,从根源上修复路径逻辑:
在你的Webpack配置中,把node选项里的__dirname改为false:
node: { __filename: true, __dirname: false // 改为false,恢复Node.js原生的__dirname行为 },
为什么这能行?
当__dirname设为false时,Webpack不会替换这个变量,它会保持Node.js的原生行为——指向源码文件实际所在的目录(也就是src/models/)。这样Sequelize自动生成的index.js里的path.join(__dirname, file)就能正确找到同目录下的模型文件了。
备选方案:基于项目根目录加载模型
如果因为某些原因不能修改Webpack的__dirname配置,可以调整src/models/index.js的路径逻辑,基于项目根目录来定位模型:
// 替换原来的var model = sequelize['import'](path.join(__dirname, file)); const projectRoot = path.resolve(process.cwd()); // 获取项目启动时的工作目录(即my-project目录) var model = sequelize['import'](path.join(projectRoot, 'src/models', file));
这种方式不依赖__dirname,只要你启动Node时的工作目录是项目根目录,就能稳定找到模型文件,不受打包路径的影响。
关于你的临时修复
你之前用path.join('../'+__dirname, file)的方式虽然能临时解决,但隐患很大:
- 它依赖当前的目录层级关系,如果后续调整Webpack输出路径或项目目录结构,这个相对路径会直接失效;
- 其他依赖
__dirname的文件也可能出现类似的路径问题,需要逐个修改,维护成本很高。
所以优先推荐第一种修改Webpack配置的方案,一劳永逸解决问题。
内容的提问来源于stack exchange,提问作者SyncroIT

