Javascript ES6 TypeError:没有'new'就不能调用类构造函数客户端

IT技术 javascript node.js ecmascript-6
2021-01-24 08:55:22

我有一个用 Javascript ES6 编写的类。当我尝试执行nodemon命令时,我总是看到这个错误TypeError: Class constructor Client cannot be invoked without 'new'

下面提到了完整的错误:

/Users/akshaysood/Blockchain/fabricSDK/dist/application/Transaction.js:45
        return (0, _possibleConstructorReturn3.default)(this, (FBClient.__proto__ || (0, _getPrototypeOf2.default)(FBClient)).call(this, props));
                                                                                                                              ^

TypeError: Class constructor Client cannot be invoked without 'new'
    at new FBClient (/Users/akshaysood/Blockchain/fabricSDK/dist/application/Transaction.js:45:127)
    at Object.<anonymous> (/Users/akshaysood/Blockchain/fabricSDK/dist/application/Transaction.js:195:14)
    at Module._compile (module.js:641:30)
    at Object.Module._extensions..js (module.js:652:10)
    at Module.load (module.js:560:32)
    at tryModuleLoad (module.js:503:12)
    at Function.Module._load (module.js:495:3)
    at Module.require (module.js:585:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/akshaysood/Blockchain/fabricSDK/dist/routes/users.js:11:20)

我想要做的是,我创建了一个类,然后创建了该类的一个实例。然后我试图导出该变量。

类结构定义如下:

class FBClient extends FabricClient{

    constructor(props){
        super(props);
    }

<<< FUNCTIONS >>>

}

我如何尝试导出变量 ->

var client = new FBClient();
client.loadFromConfig(config);

export default client = client;

你可以在这里找到完整的代码 > https://hastebin.com/kecacenita.js Babel 生成的代码 > https://hastebin.com/fabewecumo.js

6个回答

问题是该类扩展了原生 ES6 类,并使用 Babel 转换为 ES5。转译的类不能扩展本地类,至少在没有额外措施的情况下是这样。

class TranspiledFoo extends NativeBar {
  constructor() {
    super();
  }
}

结果像

function TranspiledFoo() {
  var _this = NativeBar.call(this) || this;
  return _this;
}
// prototypically inherit from NativeBar 

由于 ES6 类只应使用 调用new,因此会NativeBar.call导致错误。

任何最新的 Node 版本都支持 ES6 类,它们不应该被转译。es2015应该从 Babel 配置中排除,最好使用env预设设置为nodetarget

同样的问题也适用于 TypeScript编译器应该正确配置为不转译类,以便它们从本机或 Babel 类继承。

该手册涵盖了babeljs.io/docs/en/babel-preset-env使用“目标节点”。
2021-03-14 08:55:22
正如答案所说。将 Babel 配置更改为不转译为 ES5。es2015预设负责这种行为。
2021-04-04 08:55:22
@jchook 从技术上讲,它的工作原理类似于function A() { if (!new.target) throw new Error('cannot be invoked without new') }. A有它的条款,但它绝对是一个函数。
2021-04-06 08:55:22
如果我不使用 Babel 将 ES6 转换为 ES5。它抛出错误:意外的令牌导入:
2021-04-07 08:55:22
@Haroldo_OK 确实,至少如果这意味着支持旧版浏览器(浏览器应用程序在 2020 年不一定是 ES5)。如果存在扩展内置类(Error、Promise 等)的类,则应以特殊方式扩展它以与 ES5 兼容,这在 SO 的其他问题中有所介绍。如果一个类扩展了原生 ES6 类,那么 ES5 应用程序中存在未转译的类才是真正的问题。
2021-04-11 08:55:22

我转译的不是 Javascript 而是 Typescript,遇到了同样的问题。

我编辑了 Typescript 编译器配置文件tsconfig.json,以生成 ES2017 Javascript 代码:

{
    "compilerOptions": {
        "target": "ES2017",

而不是默认值,ES2015?- 然后一切正常。

(也许这个答案对使用 Typescript 并在搜索相同错误消息时找到这个问题的人有所帮助,就像我一样。)

为我工作。谢谢!
2021-04-05 08:55:22

package.json你可以使用目标配置与@babel/preset-env设置esmodules为“真”。

下面是我如何在我的文件中使用的示例:

  "babel": {
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": {
            "esmodules": true
          }
        }
      ],
      "@babel/preset-react",
      "@babel/preset-flow"
    ],
    "plugins": [
      "@babel/plugin-proposal-class-properties"
    ]
  },

对于那些谁使用TS-节点,它可能是可能是您tsconfig.json无法通过加载TS-节点

  1. 确保您已为以下选项设置tsconfig.json
    {
        "compilerOptions": {
            "target": "ES6",
            ...
        }
    }
  1. 尝试ts-node --script-mode或使用--project来指定您的tsconfig.json.

对于 Angular 9+,这也可能是使用 typescript 编译标志的问题:

  • downlevelIteration
  • importHelpers

更多信息请访问https://www.typescriptlang.org/tsconfig#downlevelIteration

尝试在您的tsconfig.josn

{
    "compilerOptions": {
        ...
        "downlevelIteration": true,
        "importHelpers": true,
        ...
    }
}

没有"importHelpers": true它也应该有效。


此解决方案主要用于 Angular 9+ 和 ngcc 编译器 - 这是 Angular 11 发生的问题。由于有 Angular,所以维护了包的自定义配置(自定义 ng-packgr 配置 - Angular CLI 库生成在 Angular 6 中引入)项目4+。将这些包迁移到 Angular 9+ 库(项目文件夹)后,错误开始发生。我发现这些标志(严格来说是 downlevelIteration)正好解决了这个问题。