You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js集成Sequelize时出现Webpack依赖报错问题

问题场景

在Next.js项目的pages/api/submitAllegationApi.js文件中引入Sequelize数据模型,执行新数据条目创建操作时存在如下异常:

  • 单独调用api/submitAllegationApi接口无任何报错
  • 先调用其他API路由,再调用该接口时抛出两类错误:
    1. Webpack警告:Critical dependency: the request of a dependency is an expression,指向./models/index.js
    2. 运行时错误:MODULE_NOT_FOUND,提示找不到.next/server/pages/api/pdfcreate.js文件

完整错误栈:

error - Error: Cannot find module '/Users/Desktop/.../.next/server/pages/api/pdfcreate.js'
at webpackEmptyContext (/Users/Desktop/.../.next/server/pages/api/submitAllegationApi.js:22:10)
at eval (webpack-internal:///(api)/./models/index.js:18:65)
at Array.forEach ()
at eval (webpack-internal:///(api)/./models/index.js:17:4)
at Object.(api)/./models/index.js (/Users/.../.next/server/pages/api/submitAllegationApi.js:84:1)
at webpack_require (/Users/.../.next/server/webpack-api-runtime.js:33:42)
at eval (webpack-internal:///(api)/./pages/api/submitAllegationApi.js:6:24)
at Object.(api)/./pages/api/submitAllegationApi.js (/Users/.../.next/server/pages/api/submitAllegationApi.js:95:1)
at webpack_require (/Users/.../.next/server/webpack-api-runtime.js:33:42)
at webpack_exec (/Users/.../.next/server/pages/api/submitAllegationApi.js:116:39) {
code: 'MODULE_NOT_FOUND'
}

涉及的原始代码:

  1. submitAllegationApi.js
const db = require('../../models/index');
const { DataTypes } = require("sequelize");
const Allegations=require("../../models/Allegations")(db.sequelize, db.Sequelize.DataTypes);
export default async function handler(req, res){
     var data= req.body;
      Allegations.create({
        faculty: data.Faculty
        // 其余业务字段省略

    })
    console.log("received: "+data);
    res.status(200).send(data);
  };
  1. Allegations模型文件
'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Allegations extends Model {
 
    static associate(models) {
      // 关联关系定义省略
    }
  }
  Allegations.init({
    faculty: DataTypes.STRING
    // 其余模型字段省略
  }, {
    sequelize,
    modelName: 'Allegations',
  });
  return Allegations;
};
  1. models/index.js
'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;
根因定位
  • 核心问题出在models/index.js的动态加载逻辑:Sequelize CLI默认生成的代码用fs.readdirSync遍历目录+path.join拼接路径做动态require,这种写法在Node.js原生环境可以正常运行,但Next.js会用Webpack对API路由代码做静态打包,Webpack无法解析表达式形式的动态依赖路径,因此抛出关键依赖警告。
  • 动态require会让Webpack错误地将依赖解析上下文匹配到pages/api目录,当其他API路由(比如pdfcreate.js)被调用后,Webpack的上下文缓存被污染,遍历加载模型时会尝试去API目录下找文件,最终抛出模块找不到的错误。
  • 额外问题:submitAllegationApi.js中重复引入并初始化了Allegations模型,和models/index.js中已经加载的模型实例冲突,会进一步放大打包后的路径解析异常。
修复方案

1. 修改models/index.js,替换动态遍历为静态显式引入

去掉fs遍历和动态require的逻辑,手动逐个引入所有模型,让Webpack可以正常静态解析依赖路径,修改后代码如下:

'use strict';

const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

// 静态引入所有模型,替代原动态遍历逻辑
db.Allegations = require('./Allegations')(sequelize, Sequelize.DataTypes);
// 其余模型按相同格式在此处引入即可
// db.XXXModel = require('./XXXModel')(sequelize, Sequelize.DataTypes);

// 执行模型关联
Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

2. 修改submitAllegationApi.js,移除重复的模型初始化

直接从db对象中取已经初始化完成的模型实例,不要单独重复引入模型文件,修改后代码如下:

const db = require('../../models/index');
export default async function handler(req, res){
  const data = req.body;
  // 直接使用预加载的模型,注意异步操作加await避免未捕获异常
  await db.Allegations.create({
    faculty: data.Faculty
    // 其余业务字段和原逻辑一致
  })
  console.log("received: ", data);
  res.status(200).send(data);
};

可选优化(模型数量较多场景)

如果项目模型数量多,不想逐个手动写引入,可以在next.config.js中配置将models目录标记为服务端外部依赖,不经过Webpack打包处理,配置示例:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config, { isServer }) => {
    if (isServer) {
      config.externals.push(function ({ request }, callback) {
        if (request && request.includes('/models/')) {
          return callback(null, 'commonjs ' + request);
        }
        callback();
      });
    }
    return config;
  },
}

module.exports = nextConfig;

注意:该配置需要配合Next.js版本适配,显式静态引入是兼容性最稳定的方案。


内容的提问来源于stack exchange,提问作者shardul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:06:30