使用 SystemJS 和 TypeScript 从捆绑文件中执行模块

And*_*nov 6 amd typescript systemjs

我有一个包含 2 个类的简单 TypeScript 项目:Main.ts 和 Ball.ts,首先是导入第二个。我正在尝试创建一个类似于 AS3 项目的设置,其中有一个入口点类可以触发所有其他事情的发生。我想将所有 js 编译成一个文件,以便我可以更有效地加载它。我有的文件:

主文件

import Ball from "./Ball";

class Main {
    a: number = 10;

    constructor() {
        console.log("Hello from Main!");
        let ball:Ball = new Ball();
    }
}

let main = new Main();
Run Code Online (Sandbox Code Playgroud)

Ball.ts

export default class Ball{
    shape:string = "round";
    constructor(){
        console.log("Ball has been created");
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用的 TS 配置:

{
  "compilerOptions": {
        "target": "es5",
        "module": "amd", 
        "outFile": "./public/js/bundle.js",
        "strict": true
    }
}
Run Code Online (Sandbox Code Playgroud)

要在 js 中使用 amd 模块,我使用 SystemJS:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Hello</h1>
<script type="text/javascript" src="js/system.js"></script>
<script>
    SystemJS.config({
        baseURL: '/js'
    });
    SystemJS.import('bundle.js');
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

编译后的js文件如下所示:

define("Ball", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Ball = (function () {
        function Ball() {
            this.shape = "round";
            console.log("Ball has been created");
        }
        return Ball;
    }());
    exports.default = Ball;
});
define("Main", ["require", "exports", "Ball"], function (require, exports, Ball_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Main = (function () {
        function Main() {
            this.a = 10;
            console.log("Hello from Main!");
            var ball = new Ball_1.default();
        }
        return Main;
    }());
    var main = new Main();
});
Run Code Online (Sandbox Code Playgroud)

正如我所看到的,编译过程没有问题,但是当我在浏览器中查看结果代码时,我没有看到任何运行,没有 console.log 语句被触发到控制台。bundle.js 本身正在加载状态为 200 的网络选项卡,所以我假设 SystemJS 请求它并正确加载内容,但是如何触发 Main 模块?我也尝试使用系统类型模块,但它给出了相同的结果。

Lou*_*uis 6

问题

当您执行SystemJS.import('bundle.js');SystemJS 时,使用 生成模块名称的路径baseURL,即/js/bundle.js发出 GET HTTP 请求以获取该路径。一旦它被获取,它就会bundle.js在包内寻找一个名为的模块,但没有找到它。你有两个模块,namedBallMain. (如果 AMDdefine调用的第一个参数是一个字符串,那就是模块名称。)所以你必须使用这些模块名称之一。

解决方案

Main如果您这样做,SystemJS 将搜索该模块SystemJS.import("Main")。但是,默认情况下,SystemJS 会Main以与for相同的方式为bundle.js. Main不在/js/Main但在/js/bundle.js。那么如何告诉 SystemJS 从正确的位置获取它呢?您必须使用bundles配置选项:

SystemJS.config({
    baseURL: "/js",
    bundles: {
        "bundle.js": ["Main"],
    },
});
SystemJS.import("Main");
Run Code Online (Sandbox Code Playgroud)

上面的配置说“命名的包bundle.js包含模块Main”。(我也可以Ball在数组中列出,但在这种情况下这不是必需的。)因此,当您这样做时SystemJS.import("Main"),SystemJS 获取名为bundle.jsfrom的模块/js/bundle.js并在其中查找名为 的模块Main