Sequelize中出现Cannot read properties of undefined (reading 'define')错误求助
问题:Sequelize 实例未定义导致
Cannot read properties of undefined (reading 'define')错误 场景还原
使用Node.js + Express + TypeScript + Sequelize搭建服务时,按以下代码结构组织出现报错:
- 在
server.service.ts中初始化Sequelize实例并通过桶式导出:
// File --> server.service.ts import { Sequelize } from 'sequelize'; const sequelize: Sequelize = new Sequelize(DB_NAME, DB_USER, DB_PASSWORD, { dialect: "mysql", host: DB_HOST, pool: { idle: 10000, max: 10, min: 0 }, }); export { sequelize };
- 在
models/User.ts中导入该实例定义模型:
import { DataTypes, ModelDefined, Optional } from "sequelize"; import { Role, User as Usr } from "../types"; import { sequelize } from "../services"; type UserOptionalsAttr = Optional<Usr, "id" | "role">; const User: ModelDefined<Usr, UserOptionalsAttr> = sequelize.define( "User", { email: { allowNull: false, type: DataTypes.STRING, unique: true, validate: { isEmail: true }, }, id: { autoIncrement: true, onDelete: "CASCADE", onUpdate: "CASCADE", primaryKey: true, type: DataTypes.INTEGER, }, password: { allowNull: false, type: DataTypes.STRING, validate: { max: 16, min: 3 }, }, role: { allowNull: false, defaultValue: Role.USER, type: DataTypes.STRING, }, username: { allowNull: false, type: DataTypes.STRING }, }, { tableName: "users", timestamps: true } ); export { User };
- 在控制器中使用模型查询时触发错误:
const foundedUser = await User.findOne({ where: { email }, });
报错信息:Cannot read properties of undefined (reading 'define')
原因分析
这是循环依赖/模块加载顺序异常导致的问题。桶式导入(barrel import)会打乱模块加载顺序,当模型文件尝试导入sequelize实例时,server.service.ts可能还未完成实例初始化,导致导入的sequelize为undefined。
解决方案
1. 调整模型加载顺序,确保实例先初始化
修改server.service.ts,在Sequelize实例完全初始化后再加载所有模型:
// server.service.ts import { Sequelize } from 'sequelize'; const sequelize: Sequelize = new Sequelize(DB_NAME, DB_USER, DB_PASSWORD, { dialect: "mysql", host: DB_HOST, pool: { idle: 10000, max: 10, min: 0 }, }); // 延迟加载模型,确保实例已就绪 (async () => { await import('./models/User'); // 可添加更多模型导入 })(); export { sequelize };
2. 优化模型桶式导入结构
创建models/index.ts作为模型统一出口,确保模型在实例初始化后加载:
// models/index.ts import { sequelize } from '../services/server.service'; import { User } from './User'; // 确保模型与实例关联完成 export { User };
控制器中从模型统一入口导入:
import { User } from '../models'; // 查询代码保持不变 const foundedUser = await User.findOne({ where: { email } });
3. 检查TypeScript配置
确保tsconfig.json的模块配置支持正确的加载顺序:
{ "compilerOptions": { "module": "CommonJS", "target": "ES6", "esModuleInterop": true, "skipLibCheck": true } }
4. 避免直接从服务桶导入实例
如果使用了services/index.ts作为桶文件,直接导入具体的server.service.ts而非桶文件,减少加载顺序不确定性:
// models/User.ts // 替换 import { sequelize } from "../services"; import { sequelize } from "../services/server.service";
内容的提问来源于stack exchange,提问作者Valery Nosareu
相关产品推荐
相关产品推荐

