类型错误:如果没有“new”,则无法调用类构造函数模型

Cod*_*one 6 javascript node.js sequelize.js ecmascript-6 babeljs

我在一个应用程序中将SequelizeNodeJavaScript一起使用。如您所知,当您执行时,sequelize-init它会创建configmigrationsmodelsseeders文件夹。在models文件夹内,有一个index.js文件(由 cli 生成),它负责从当前文件夹中读取所有模型及其关联:

索引.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;
Run Code Online (Sandbox Code Playgroud)

当我运行我的应用程序时,出现错误:TypeError: Class constructor model cannot be invoked without 'new' at line 17 这是语句:var model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes );阅读与此问题相关的一些帖子,我发现我需要将软件包@babel/preset-env@babel/cli, @babel/core, @babel/node. 我还在.babelrc根目录中创建了一个文件,其中包含以下代码:

.babelrc

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": {
            "esmodules": true
          }
        }
      ]
    ]
}
Run Code Online (Sandbox Code Playgroud)

并将我的标签start选项更新为:(我不使用 webpack)scriptspackage.json"nodemon --exec babel-node app.js"

但是当我运行该应用程序时,错误仍然出现。我错过了什么或没有正确设置什么?

Moh*_*lal 22

注意:最后检查“原因”部分!如果你想知道的话。

问题

问题是ES6 类 => 没有转译为 ES5 的全部功能!Sequelize 依赖于一些功能

或者

使用Sequelize.import来代替要求!不!(Babel 或任何转译器与 require (或 es import)一起工作,以及sequelize.import 工作如何导致问题!)!

回答

我猜你正在使用

export class Course extends Model {} // <== ES6 classes

Course.init({
Run Code Online (Sandbox Code Playgroud)

你的 babel 配置就是造成这种情况的原因!

你可以在这个 github 线程评论上查看

这对那家伙有用

export class Course extends Model {} // <== ES6 classes

Course.init({
Run Code Online (Sandbox Code Playgroud)

或者

{
  "presets": [
    ["env", {
      "targets": {
        "node": "current"
      }
    }]
  ]
}
Run Code Online (Sandbox Code Playgroud)

评论

让 babel 使用 ES6 类!

请注意,如果另一方面你只是坚持 sequelize.define()下去

export const User = sequelize.define('User', {
  // Model attributes are defined here
  firstName: {
    type: DataTypes.STRING,
    allowNull: false
  },
Run Code Online (Sandbox Code Playgroud)

它在 ES5 中运行得很好!

不要使用 Sequelize.import 导入模型

如果你正在这样做,那就不要这样做!使用require或 es import! 转译器不直接处理 Sequelize.import!这似乎会引起问题

评论显示

对我来说,这是因为 ES6 和 Typescript

打字稿

默认目标是ES5

将其更改为ES6+!全部开始工作!

例如

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": true
        }
      }
    ]
  ]
}
Run Code Online (Sandbox Code Playgroud)

ES5 与sequ​​elize.define 有效

要知道,ES5 与sequ​​elize.define 工作得很好!

在此输入图像描述

带 Class 扩展的 ES5 不起作用

在此输入图像描述

插图

在此输入图像描述

ES6+ 始终有效

在此输入图像描述

在此输入图像描述

为什么!Babel 通常不会正确转译!???

你可以在这个 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

这里有一篇文章(compare- different-ways-of-transpiling-es6-class-to-es5),详细介绍了该主题