使用 SystemJS 和 TypeScript 从捆绑文件中执行模块
Executing a module from a bundled file using SystemJS and TypeScript
我有一个简单的 TypeScript 项目,其中包含 2 个 classes:Main.ts 和 Ball.ts,第一个是导入第二个。我正在尝试创建一个类似于 AS3 项目的设置,其中您有一个入口点 class 可以触发所有其他事情的发生。我想将所有 js 编译成一个文件,这样我就可以更有效地加载它。
我拥有的文件:
Main.ts
import Ball from "./Ball";
class Main {
a: number = 10;
constructor() {
console.log("Hello from Main!");
let ball:Ball = new Ball();
}
}
let main = new Main();
Ball.ts
export default class Ball{
shape:string = "round";
constructor(){
console.log("Ball has been created");
}
}
我正在使用的 TS 配置:
{
"compilerOptions": {
"target": "es5",
"module": "amd",
"outFile": "./public/js/bundle.js",
"strict": true
}
}
要在 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>
编译后的 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();
});
如我所见,编译过程没有问题,但当我在浏览器中查看结果代码时,我没有看到任何东西 运行,没有 console.log 语句被触发到控制台。 bundle.js 本身正在网络选项卡中加载,状态为 200,所以我假设 SystemJS 请求它并正确加载内容,但我如何触发 Main 模块?我也尝试使用系统类型模块,但它给出了相同的结果。
问题
当您执行 SystemJS.import('bundle.js');
时,SystemJS 使用 baseURL
创建模块名称的路径,即 /js/bundle.js
并发出 GET HTTP 请求以获取该路径。获取后,它会在包中查找名为 bundle.js
的模块,但没有找到。您有两个模块,名为 Ball
和 Main
。 (如果 AMD 的 define
调用的第一个参数是一个字符串,那就是模块名称。)因此您必须使用其中一个模块名称。
解决方案
如果您SystemJS.import("Main")
,SystemJS 将搜索模块Main
。但是,默认情况下,SystemJS 将以与 bundle.js
相同的方式为 Main
创建路径。 Main
不在 /js/Main
中,而是在 /js/bundle.js
中。那么如何告诉 SystemJS 从正确的地方获取它呢?您必须使用 bundles
配置选项:
SystemJS.config({
baseURL: "/js",
bundles: {
"bundle.js": ["Main"],
},
});
SystemJS.import("Main");
上面的配置表示"the bundle named bundle.js
contains the module Main
"。 (我也可以在数组中列出 Ball
,但在这种情况下没有必要。)因此,当您执行 SystemJS.import("Main")
时,SystemJS 从 /js/bundle.js
中获取名为 bundle.js
的模块,并且在其中查找名为 Main
.
的模块
我有一个简单的 TypeScript 项目,其中包含 2 个 classes:Main.ts 和 Ball.ts,第一个是导入第二个。我正在尝试创建一个类似于 AS3 项目的设置,其中您有一个入口点 class 可以触发所有其他事情的发生。我想将所有 js 编译成一个文件,这样我就可以更有效地加载它。 我拥有的文件:
Main.ts
import Ball from "./Ball";
class Main {
a: number = 10;
constructor() {
console.log("Hello from Main!");
let ball:Ball = new Ball();
}
}
let main = new Main();
Ball.ts
export default class Ball{
shape:string = "round";
constructor(){
console.log("Ball has been created");
}
}
我正在使用的 TS 配置:
{
"compilerOptions": {
"target": "es5",
"module": "amd",
"outFile": "./public/js/bundle.js",
"strict": true
}
}
要在 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>
编译后的 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();
});
如我所见,编译过程没有问题,但当我在浏览器中查看结果代码时,我没有看到任何东西 运行,没有 console.log 语句被触发到控制台。 bundle.js 本身正在网络选项卡中加载,状态为 200,所以我假设 SystemJS 请求它并正确加载内容,但我如何触发 Main 模块?我也尝试使用系统类型模块,但它给出了相同的结果。
问题
当您执行 SystemJS.import('bundle.js');
时,SystemJS 使用 baseURL
创建模块名称的路径,即 /js/bundle.js
并发出 GET HTTP 请求以获取该路径。获取后,它会在包中查找名为 bundle.js
的模块,但没有找到。您有两个模块,名为 Ball
和 Main
。 (如果 AMD 的 define
调用的第一个参数是一个字符串,那就是模块名称。)因此您必须使用其中一个模块名称。
解决方案
如果您SystemJS.import("Main")
,SystemJS 将搜索模块Main
。但是,默认情况下,SystemJS 将以与 bundle.js
相同的方式为 Main
创建路径。 Main
不在 /js/Main
中,而是在 /js/bundle.js
中。那么如何告诉 SystemJS 从正确的地方获取它呢?您必须使用 bundles
配置选项:
SystemJS.config({
baseURL: "/js",
bundles: {
"bundle.js": ["Main"],
},
});
SystemJS.import("Main");
上面的配置表示"the bundle named bundle.js
contains the module Main
"。 (我也可以在数组中列出 Ball
,但在这种情况下没有必要。)因此,当您执行 SystemJS.import("Main")
时,SystemJS 从 /js/bundle.js
中获取名为 bundle.js
的模块,并且在其中查找名为 Main
.