【问题标题】:Fix Class is not a constructor error when using namespace in TypeScript with WebPack在 TypeScript 中使用命名空间和 WebPack 时修复类不是构造函数错误
【发布时间】:2021-03-27 10:37:57
【问题描述】:

概述
我不熟悉在没有框架的情况下使用 TypeScript 和 PIXI.js。我曾经使用语言/库来工作,我们使用带有模块关键字的命名空间。我一直在尝试复制我们使用的设置,因为我认为它看起来比加载大量导入语句要好得多。

问题
当我在浏览器中运行我的代码时,我在 windows 检查器控制台中收到以下错误:

Uncaught TypeError: MyApp.AbstractModel is not a constructor
    at Main../src/Main.ts.Main.createModel (Main.ts:16)

我发现和尝试的修复方法
我已经阅读了很多次找到的命名空间的打字稿文档herehere,但看不到我哪里出错了。

最初我认为问题在于并非所有文件都被 webpack 加载,但我通过找到的建议修复了这个问题 here(即“require.context()”),但错误仍然存​​在。

我尝试从主文件导入命名空间(将 Main 中的内容复制到 Game.ts,并将以下内容放入 Main.ts)

require.context("../src/", true, /\.ts$/);
/// <reference path="Game.ts" />

class Main {

    constructor() {
        console.log("Main.constructor()");
        new MyApp.Game();
    }

}
new Main();

结构
我的文件结构如下:

stack-overflow-example
| - .idea
| - dev
| | - dts
| | | <all .d.ts files from tsc compilation>
| | - js
| | | <all .js files and accompanying .js.map files from compiled .ts files>
| | - index.html
| - node_modules
| - src
| | - graphics
| | | - pixi-manager.ts
| | - model
| | | - AbstractModel.ts
| | - Main.ts
| | - refs.ts
| package.json
| package-lock.json
| tsconfig.json
| webpack.config.js

守则
index.html

<!DOCTYPE html>
<html>
    <head>
        <title>stack-overflow-example</title>
    </head>
    <body>
        <script src="js/Bundle.js" type="text/javascript"></script>
    </body>
</html>

维护.ts

/// <reference path="refs.ts" />
require.context("../src/", true, /\.ts$/);

namespace MyApp {
    export class Main {

        public static instance: Main = new Main();
        public model: AbstractModel;

        constructor() {
            console.log("Main.constructor()");
            this.createModel();
        }

        protected createModel(): void {
            this.model = new AbstractModel();
        }

        protected addComponent(view: PIXI.DisplayObject): void {
            PixiManager.instance.stage.addChild(view);
        }

        public getModel(): AbstractModel {
            return this.model;
        }
    }
}

AbstractModel.ts

/// <reference path="../refs.ts" />
namespace MyApp {
    export class AbstractModel {

        constructor() {
            console.log("AbstractModel.constructor()");
        }

    }
}

refs.ts

/// <reference path="graphics/pixi-manager.ts" />
/// <reference path="model/AbstractModel.ts" />
/// <reference path="Main.ts" />

package.json

{
  "name": "my-game",
  "version": "1.0.0",
  "description": "",
  "main": "Main.ts",
  "scripts": {
    "start": "webpack-dev-server --content-base dev/ --inline --hot"
  },
  "devDependencies": {...}
}

tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dev/js/",
    "module": "commonjs",
    "target": "ES5",
    "sourceMap": true,
    "declaration": true,
    "declarationDir": "./dev/dts"
  },
  "include": ["./src/*.ts"]
}

webpack.config.js

var path = require("path");
module.exports = {
    entry: {
        namespace: "./src/Main.ts"
    },
    mode: "development",
    devtool: "source-map",
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ],
    },
    output: {
        path: path.resolve(__dirname, "dev/js/"),
        filename: "js/Bundle.js"
    }
};

问题
如何在保持命名空间样式而不是使用模块的同时修复“MyApp.AbstractModel 不是构造函数”错误?

非常感谢您的所有帮助,感谢您的宝贵时间。

【问题讨论】:

    标签: typescript webpack webpack-dev-server pixi.js tsc


    【解决方案1】:

    首先请检查为什么会发生is not a constructor 错误:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_constructor。似乎AbstractModel 可能未定义错误发生的位置。

    你可以这样检查:

            protected createModel(): void {
                console.log(typeof AbstractModel);
                this.model = new AbstractModel();
            }
    

    如果是这样,那么您应该将此问题更改为:“如何从 TypeScript 和 WebPack 的目录中加载所有类?”。

    然后,您想使用require.context(... 方法做的事情可以按照以下说明完成:Is it possible to import modules from all files in a directory, using a wildcard?

    但是还请阅读以下文档:

    如您所见,有些人认为这是一种不好的做法。我也更喜欢显式枚举当前文件的所有依赖项。这样您就可以准确地看到在哪里使用了什么。 IDE 也应该可以帮助您。

    下一个问题是 &lt;reference path...import 的用法。首先你说:

    ...因为我认为它看起来比拥有大量 import 语句要好得多。

    但是在refs.ts 你这样做:

    /// <reference path="graphics/pixi-manager.ts" />
    /// <reference path="model/AbstractModel.ts" />
    /// <reference path="Main.ts" />
    

    所以不是使用 loads of import statements 你有 loads of reference statements :) 。代码行数似乎与您使用导入时相同。

    另外,请再次查看您在问题中链接的文档中的示例:https://www.typescriptlang.org/docs/handbook/namespaces.html#multi-file-namespaces - 在Test.ts 文件中,每个需要的文件都有&lt;reference

    /// <reference path="Validation.ts" />
    /// <reference path="LettersOnlyValidator.ts" />
    /// <reference path="ZipCodeValidator.ts" />
    
    ...
    

    在文件LettersOnlyValidator.tsZipCodeValidator.ts 中引用了/// &lt;reference path="Validation.ts" /&gt; - 但在最后一个文件中他们需要再次引用/// &lt;reference path="Validation.ts" /&gt; - 所以这意味着“引用路径方法”不是transitive

    这意味着您最好重新考虑这一点,并在需要时尝试使用import(和/或export)。

    【讨论】:

      猜你喜欢
      • 2018-05-01
      • 1970-01-01
      • 2016-03-16
      • 2016-05-16
      • 2012-01-12
      • 1970-01-01
      • 2023-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多