I have a simple TypeScript project with 2 classes: Main.ts and Ball.ts, first is importing the second one. I'm trying to create a setup similar to AS3 project, where you have one entry point class that triggers all other things to happen. I want to compile all js into a single file so I could load it more efficiently. Files I have:
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 Configuration I'm using:
{
"compilerOptions": {
"target": "es5",
"module": "amd",
"outFile": "./public/js/bundle.js",
"strict": true
}
}
To use amd modules in js I use 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>
Compiled js file looks like this:
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();
});
as I can see, compilation process has no issues, though when I'm viewing resulted code in the browser I don't see anything running, no console.log statements are being triggered to the console. bundle.js itself is loading in the network tab with a status of 200 so I assume SystemJS requesting it and loading the contents correctly, but how can I trigger Main module? I also tried to use system type modules but it gave the same result.
When you do SystemJS.import('bundle.js');
SystemJS makes a path of of the module name by using baseURL
, which is /js/bundle.js
and issues a GET HTTP request to fetch that. Once it is fetched, it looks for a module named bundle.js
inside the bundle, and does not find it. You have two modules, named Ball
and Main
. (If first argument to AMD's define
call is a string, that's the module name.) So you have to use one of these module names.
SystemJS will search for the module Main
if you do SystemJS.import("Main")
. However, by default, SystemJS will create a path for Main
in the same way it does for bundle.js
. Main
is not in /js/Main
but in /js/bundle.js
. So how to tell SystemJS to fetch it from the right place? You have to use the bundles
configuration option:
SystemJS.config({
baseURL: "/js",
bundles: {
"bundle.js": ["Main"],
},
});
SystemJS.import("Main");
The configuration above says "the bundle named bundle.js
contains the module Main
". (I could have also listed Ball
in the array but that's not necessary in this case.) So when you do SystemJS.import("Main")
, SystemJS fetches the module named bundle.js
from /js/bundle.js
and looks in it for the module named Main
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With