1.问题描述
最近编写了一个koa2的项目中使用了sequelize-typescript,按照官网给出的模型加载方法,将sequlize配置文件中写入模型所在路径,并按照规范将模型命名为xxx.model.ts的形式。 sequlize配置文件如下:
export const MYSQL_CONF: SequelizeOptions = {
host: "localhost",
username: "database_username",
password: "database_password",
port: 3306,
database: "database_name",
dialect: "mysql",
models: [path.join(__dirname, "..", "/db/models/*.model.ts")],
};
开发环境使用的是ts-node-dev进行热更新,没有问题。但当我使用tsc将代码转译为es5语法时问题出现,对sequlize模型进行查询等操作时,报出can't found (sequelize操作) of undefined的错误。
2.原因分析
根据报错大致可以推断模型加载出了问题,于是翻看sequelize-typescript官方文档,看到加载模型有两种方式,一种是通过设置路径自动加载,另一种是通过sequelize.addModels()方法按需手动加载。并且文档中最下面有这么一句提示:
⚠When using paths to add models, keep in mind that they will be loaded during runtime. This means that the path may differ from development time to execution time. For instance, using .ts extension within paths will only work together with [ts-node].
大致意思是根据路径自动加载模型的方法会根据运行环境不同存在差异,例如ts后缀的模型只在ts-node环境下有效,tsc转译可能会出现路径解析错误的现象。
3.解决方案
解决方案很简单,只要把原来设置中的models项去掉,然后在sequelize引入时手动加载模型就可以了。代码如下:
import { Sequelize } from "sequelize-typescript";
import { MYSQL_CONF } from "../conf/db";
// 引入所有模型定义
import Models from "./models/index";
const seq = new Sequelize(MYSQL_CONF);
// 遍历所有模型,手动添加到sequelize实例
// 如果使用自动根据路径添加模型,tsc编译后将出现错误
const models: any[] = [];
for (const model in Models) {
models.push((Models as any)[model]);
}
seq.addModels(models);
export default seq;