TypeError:类扩展值undefined不是构造函数或null

时间:2018-02-04 00:33:38

标签: javascript node.js

这个问题导致我在过去几天失去理智。

这是我的目录结构:

[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"以查看它是否过于“高级”的问题,但我得到了关于超级函数(或其他)的不同错误,我认为这是同样的问题。 / p>

以下是从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/,仍然打破了。我在console.log(Command)中尝试了cmds/,但他们都返回了undefined

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

9 个答案:

答案 0 :(得分:5)

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

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

如果导入/ require语句不止几个,我建议定期运行诸如Madge之类的检查器,以查找并可视化任何循环,以免它们变得难以撤消。

npm i --saveDev madge
node_modules/madge/bin/cli.js --warning --circular --extensions js ./

答案 1 :(得分:2)

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

module.exports.Command;

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

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

答案 2 :(得分:1)

在我的情况下:我正在导入一个不存在的类:

Counter.js:

import React, { Compontent } from 'react';

class Counter extends Compontent {

App.js:

import React from 'react';
import Counter from './components/Counter';

function App() {

答案 3 :(得分:0)

我收到了这样的错误:“ Sequelize TypeError:类扩展未定义的值不是构造函数或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 :(得分:0)

对于使用JSweet java进行JavaScript编译器时遇到此错误的人,我能够通过启用here所述的'bundle'选项来解决此问题:

将所有生成的代码捆绑在一个文件中,可以使用 在浏览器中。捆绑文件称为“ bundle.ts”, “ bundle.d.ts”或“ bundle.js”,具体取决于生成的代码类型。 注意:捆绑包与除以下以外的任何其他模块都不兼容 “没有”。

这是我的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 :(得分:0)

在我的情况下,这样扩展React.Component之后,我犯了一个愚蠢的错误:在括号内放上括号:

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

删除括号可修复错误。

答案 6 :(得分:0)

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

export declare abstract class Something {

应该是(当然):

export abstract class Something {

答案 7 :(得分:0)

我在 Angular 上遇到了这个错误,当运行 cypress 时,“class extends value undefined is not a constructor or null”并通过更改编译器选项是 tsconfig.json 来解决它。

来自:

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

到:

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

答案 8 :(得分:0)

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

yarn global install dpdmnpm i -g dpdm

那么 dpdm file.jsdpdm file.ts

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