【问题标题】:TypeError: Class extends value undefined is not a constructor or nullTypeError: Class extends value undefined is not a constructor or null
【发布时间】:2018-07-14 04:27:47
【问题描述】:

过去几天,这个问题一直让我失去理智。

这是我的目录结构:

[src]
|- cmds/
|  |- Gh.js
|  \- Help.js
|- commands.js
|...

我正在尝试将commands.js 导出的类导入Help.jsGh.js(以及我将来可能添加的任何其他文件)。但是,我不断收到错误消息:

class Gh extends _commands.Command {
                           ^
TypeError: Class extends value undefined is not a constructor or null

所有文件都使用 Babel 进行转译,env 设置为 "node": "current" 并使用 wildcard 包。我尝试将其设置为"browser",以查看是否是它过于“高级”的问题,但我得到了一个关于超级函数(或其他东西)的不同错误,我认为这是同一个问题。

这是从commands.js 导出的类:

export class Command {
  constructor (msg) {
    this.id = msg.author.id
    this.msg = msg
  }
  action () {}
  get data () {
    return readData().user[this.id]
  }
  updateUserData (key, val) {
    updateUserData(this.id, key, val)
  }
  sendMsg (data) {
    sendMsg(this.msg, data)
  } 
}

...这里是cmds/Gh.js,这是我尝试将Command 导入的文件之一:

import {Command} from '../commands'

export class Gh extends Command {
  constructor (msg) {
    super(msg)
    this.desc = 'Returns GitHub repository link and exits'
  }
  action () {
    this.sendMsg('GitHub link: https://github.com/owm111/knife-wife')
  }
}

我尝试将Command 放入两个cmds/,并且它们运行良好。然而,当它移回commands.js 时,它又坏了。我尝试将它导入的路径从../commands 更改为./../commands../commands.js./../commands.js;没有工作。我将commands.js 移动到cmds/,仍然破产。我在两个cmds/ 中都尝试了console.log(Command),但他们都返回了undefined

所有这一切都让它看起来像是一个导入问题,但我无法弄清楚这对我的生活有什么影响。请帮忙。

【问题讨论】:

标签: javascript node.js


【解决方案1】:

这只是对 node.js 的一个简单修复。从您的班级中删除导出并在文件的底部将其放入其中。

module.exports.Command;

现在,如果您想在任何地方使用命令类,您只需将它放在您想使用它的每个文件中。

var { Command } = require('Command.js');

【讨论】:

  • 我尝试输入您所说的内容,但我收到了 linter 错误,显示为 'Command' is defined but never used.Expected an assignment or function call and instead saw an expression.。我将行更改为module.exports.Command = Command,它消除了错误,但同样的问题。我删除了`= Command`并禁用了linter,但问题中提到了同样的问题。我认为它没有什么不同,因为正如问题中所述,我正在通过 Babel 进行编译。
【解决方案2】:

如果其他人看到这个错误,首先要查找的是循环依赖。将文件 A 导入 B,将 B 导入其他文件 C,依此类推。如果 C 到 Z 中的任何一个被导入到 A 中,那么 JS 将无法确保在另一个文件需要它的时候定义了一个文件(并且不会尝试返回并稍后填写空白)。

这里很可能是这种情况,因为显然没有发布其他代码,并且仅在引入文件依赖项时出现。 无论文件结构如何都存在问题:唯一能保证避免它的结构是单个巨大的 JS 文件。解决方案是确保类之间关系的严格树结构,并使用工厂方法或替代通信(如发射器)保持耦合松散。

如果您有多个 import / require 语句,我建议您定期运行像 Madge 这样的检查器,以便在任何循环难以撤消之前找到并可视化它们。

npm install --save-dev madge
node_modules/madge/bin/cli.js --warning --circular --extensions js ./

【讨论】:

  • 这很有趣,因为我正在通过 ESBuild 运行整个事情并且仍然收到错误:/
  • ESBuild 是否宣传循环检查及其快速捆绑/缩小?循环依赖将绕过大多数并非旨在分析整个文件结构图的项目处理工具。
  • 也许,我不确定,我从未在附近看到过任何东西。但是,我确实注意到问题来自于检查一个我没有为其定义构造函数的类。它是在它的超类中定义的。实施它就成功了。
【解决方案3】:

我得到这个错误 “Sequelize TypeError: Class extends value undefined is not a constructor or null, NodeJS” 并使用它解决了它。如果你有同样的错误,你可以使用下面我尝试在代码中解释的解决方案。

例如:

module.exports = (sequelize, DataTypes) => {

    // Modeling a table: Inheritance
    class Todo extends sequelize.Model {} // (!) Error

    // if you want to use the above line, add the following line to "lib\sequelize.js file
    // Sequelize.prototype.Model = Model; // add this line here

    class Example extends sequelize.Sequelize.Model { }

    Example.init({
        title: DataTypes.STRING,
        description: DataTypes.STRING,
        status: DataTypes.BOOLEAN
    }, {
        sequelize,
        modelName: 'todo',
        timestamps: true
    });

    return Example;
};

【讨论】:

    【解决方案4】:

    对于在使用JSweet java to javascript transpiler 时遇到此错误的人,我可以通过启用“bundle”选项来修复它,提到了here

    将所有生成的代码捆绑在一个文件中,可以使用 在浏览器中。捆绑文件称为“bundle.ts”, 'bundle.d.ts' 或 'bundle.js' 取决于生成代码的类型。 注意:bundle 不兼容任何模块类型,除了 '无'。

    这是我的 POM 的一部分,其中包含“bundle true”添加:

    <plugin>
                    <groupId>org.jsweet</groupId>
                    <artifactId>jsweet-maven-plugin</artifactId>
                    <version>${jsweet.transpiler.version}</version>
                    <configuration>
                        <verbose>true</verbose>
                        <tsOut>target/ts</tsOut>
                        <outDir>target/js</outDir>
                        <candiesJsOut>webapp</candiesJsOut>
                        <targetVersion>ES6</targetVersion>
                        <module>none</module>
                        <moduleResolution>classic</moduleResolution>
                        <bundle>true</bundle>
                    </configuration>
                    <executions>
                        <execution>
                            <id>generate-js</id>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>jsweet</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    

    然后重新运行“mvn generate-sources”,并确保更改 index.html 文件以加载新的 bundle.js 文件:

    <html>
    <head>
    <link rel="icon" type="image/png" href="logo.png">
    <link rel="shortcut icon" href="logo.png">
    <meta charset="utf-8" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
    </head>
    
    <body>
        <p>Test page</p>
        <p id="target"></p>
        <script type="text/javascript" src="../webapp/j4ts-0.7.0-SNAPSHOT/bundle.js"></script>
        <script type="text/javascript" src="../target/js/bundle.js"></script>
    </body>
    </html>
    

    【讨论】:

      【解决方案5】:

      就我而言:我正在导入一个不存在的类:

      Counter.js:

      import React, { Compontent } from 'react';
      
      class Counter extends Compontent {
      

      App.js:

      import React from 'react';
      import Counter from './components/Counter';
      
      function App() {
      

      【讨论】:

        【解决方案6】:

        在我的例子中,我犯了一个愚蠢的错误,就是在像这样扩展 React.Component 之后加上括号:

        class Classname extend React.Component() {
            ...
        

        删除括号修复了错误。

        【讨论】:

          【解决方案7】:

          另一个原因可能是您使用了以下语法(在从声明文件 (xxxx.d.ts) 复制类之后 -> xxxx.ts

          export declare abstract class Something {
          
          

          应该(当然):

          export abstract class Something {
          
          

          【讨论】:

            【解决方案8】:

            我在运行 cypress 时在 Angular“类扩展值未定义不是构造函数或 null”上收到此错误,并通过更改编译器选项解决它是 tsconfig.json。

            来自:

            "compilerOptions": {
                "baseUrl": "./",
                "downlevelIteration": true,
                "resolveJsonModule": true,
                "paths": {
                  "*": [
                    "./node_modules/*"            <== throws error
                  ],
            

            到:

              "compilerOptions": {
                "baseUrl": "./",
                "downlevelIteration": true,
                "resolveJsonModule": true,
                "paths": {
                  "*": [
                    "./node_modules/"              <== correct
                  ],
            

            【讨论】:

              【解决方案9】:

              正如其他人所提到的,这是循环依赖的结果。我尝试了几个小时来解决它。最终,它是一个名为 dpdm 的工具,它为我创造了奇迹,找到了 27 个周期并迅速解决了问题。 (我只需要解决其中的几个,其余的也都解决了。)

              yarn global add dpdmnpm i -g dpdm

              然后 dpdm file.jsdpdm file.ts

              就我而言,这发现了 Madge 和人工检查未能揭示的大量周期。很棒的工具。

              【讨论】:

                【解决方案10】:

                此错误的另一个常见原因是,如果您将 Node.js 安装到了旧版 Node.js 安装的现有折叠中。删除并重新安装 Node.js 可解决该问题。

                【讨论】:

                  猜你喜欢
                  • 2020-08-27
                  • 2022-01-09
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-10-20
                  • 2022-12-02
                  • 2021-11-02
                  • 2022-12-20
                  • 2017-08-27
                  相关资源
                  最近更新 更多