Babel.js TypeError:类构造函数模型不能在没有“new”的情况下调用

i86rm4rw  于 2023-06-20  发布在  Babel
关注(0)|答案(2)|浏览(182)

我在一个应用中使用了Sequelize,以及NodeJavaScript。正如你所知道的,当你执行sequelize-init时,它会创建 configmigrationsmodelsseeders 文件夹。在 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;

当我运行我的应用程序时,出现错误:类型错误:如果第17行没有'new',则无法调用类构造函数模型,该语句为:**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
          }
        }
      ]
    ]
}

并将package.jsonscripts标记的start选项更新为:"nodemon --exec babel-node app.js"(我不使用webpack)
但是当我运行应用程序时,错误仍然出现。我错过了什么或没有正确设置?

nxowjjhe

nxowjjhe1#

注意:最后检查为什么部分!如果你想知道的话

问题

问题是ES6的classes =>并没有完全编译到ES5中! Sequelize依赖于某些功能
或者
使用Sequelize.import代替require!不要!(Babel或任何转译器与require(或es import)和sequelize. import工作是如何导致问题的!)!

答案

我猜你在用

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

Course.init({

是你的巴别塔配置造成的!
你可以在这个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中正常工作!

不要使用Sequelize.import导入Model

如果你在做那就别做!使用require或es import!转译器不直接处理Sequelize.import!这似乎会引起问题
评论显示
对我来说,这是因为ES6与Typescript

Typescript

默认目标为ES5!
改成ES6 +!一切开始工作!
比如说,

"target": "ES2021",

使用sequelize. define的ES5可以工作

要知道ES5和sequelize.define可以很好地工作!

带Class extends的ES5不工作

图示

ES6+始终工作

为什么巴别塔通常不会正确翻译!我知道了!
你可以在这条github评论中看到
事实证明,由babel转译的ES6类不能扩展真正的ES6类(例如Sequelize.ModelES6类)。
所以类MyEntity扩展Sequelize.Model {...如果MyEntity被转译成ES5,}将不起作用。
这里的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
这里有一篇文章(comparing-different-ways-of-transpiling-es6-class-to-es5),详细介绍了这个主题

vwkv1x7d

vwkv1x7d2#

如果tsconfig.json文件中的“target”中有“es5”,则更改为“es6”。(这对我很有效,我需要编译器中的es6。)

"compilerOptions": {
    "target": "es6"
}

相关问题