我在一个应用程序中将 Sequelize 与 Node 和 JavaScript 一起使用。如您所知,当您执行
sequelize-init
时,它会创建 config、migrations、models 和 seeders 文件夹。在 models 文件夹内,有一个 index.js
文件(由 cli 生成),它负责从当前文件夹中读取所有模型及其关联:
index.js
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const sequelize = require('../database/connection');
const db = {};
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;
当我运行我的应用程序时,出现错误: TypeError: Class constructor model cannot be invoked without 'new' 在第 17 行,这是语句: var model = require(path.join(__dirname, file))(sequelize ,Sequelize.DataTypes); 阅读一些与此问题相关的 posts,我发现我需要安装
@babel/preset-env
包以及 @babel/cli, @babel/core, @babel/node
。我还在根目录下创建了一个.babelrc
文件,其中包含以下代码:
.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"esmodules": true
}
}
]
]
}
并将
start
内的 scripts
标签的 package.json
选项更新为:"nodemon --exec babel-node app.js"
(我不使用 webpack)
但是当我运行该应用程序时,错误仍然出现。我错过了什么或没有正确设置什么?
注意:最后检查“原因”部分!如果你想知道的话。
问题是 ES6 类 => 没有转译为 ES5 的完整功能! Sequelize 依赖于一些功能
或者
使用
Sequelize.import
代替 require!不! (Babel 或任何转译器与 require (或 es import)配合使用,以及sequelize.import 工作如何导致问题!)!
我猜你正在使用
export class Course extends Model {} // <== ES6 classes
Course.init({
你的 babel 配置就是造成这种情况的原因!
你可以在这个github线程上检查一下评论
这对那家伙有用
{
"presets": [
["env", {
"targets": {
"node": "current"
}
}]
]
}
或者
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
}
让 babel 使用 ES6 类!
请注意,如果在另一方面你只需坚持
sequelize.define()
方式
export const User = sequelize.define('User', {
// Model attributes are defined here
firstName: {
type: DataTypes.STRING,
allowNull: false
},
它在 ES5 中可以正常工作!
如果你正在这样做,那就不要这样做!使用
require
或 es import
!转译器不直接处理 Sequelize.import!这似乎会引起问题
评论表明
对我来说,这是因为 ES6 和 Typescript
默认目标是
ES5
!
将其更改为ES6+!一切都开始工作了!
例如
"target": "ES2021",
知道 ES5 与sequelize.define 工作得很好!
你可以在这个github中看到评论
事实证明,由 babel 转译的 ES6 类无法扩展真正的 ES6 类(例如 Sequelize.Model ES6 类)。
因此,如果 MyEntity 被转译为 ES5,则 class MyEntity extends Sequelize.Model { ... } 将不起作用。
这里 stackoverflow 的答案解释得更好: https://stackoverflow.com/a/36657312/7668448
由于 ES6 类的工作方式,您无法使用转译类来扩展本机类。如果你的平台支持原生类
您可以看到更多关于为什么以及如何可能这样的
transpilation of ES6 Class to ES5 can be done to support full features and compatiblity
的深度元素!在下面的链接中:
https://github.com/microsoft/TypeScript/issues/17088
https://github.com/microsoft/TypeScript/issues/15397
这里有一篇文章(比较 es6-class-to-es5 的不同转换方式),详细介绍了该主题
如果 tsconfig.json 文件中的“target”中有“es5”,请更改为“es6”。 (这对我有用,我需要编译器中的 es6。)
"compilerOptions": {
"target": "es6"
}
就我而言,这是因为由于某种原因,我的实体中的构造函数方法被注释了。 所以我取消了注释,它起作用了:
@Table
export class Kondo extends Model {
constructor(partial?: Partial<Kondo>) {
super();
if (partial)
Object.assign(this, partial);
}