5

I am using the typescript compiler to bundle my modules into one main.js file, using these settings in tsconfig.json:

"module": "system",
"out": "docs/js/main.js"

This works, so according to the SystemJS documentation, I only have to include the SystemJS production file and kickstart the app with these tags in my HTML:

<script src="js/system.js"></script>
<script>
  SystemJS.import('js/main.js');
</script> 

My app:

import { Message } from "./message";

export class App {
    constructor() {
        let demomessage = new Message("hello");
    }
}

export class Message {      
    constructor(str:string) {
        console.log(str);
    }
}

This results in this javascript code in main.js:

System.register("message", ...) {
    // message code here
});
System.register("app", ...) {
    // app code here
});

The part that I'm missing (and that's also not explained in Microsoft's always-lacking-Typescript-documentation) is how to actually start the app... How does SystemJS know which class is the starting point? Even if I just put console.log in my app it doesn't execute....

EDIT

I discovered that using system.js instead of system-production.js at least starts the process. After a lot of fiddling I got my app to start with the following code, but it looks weird and ugly. Is this how it's supposed to work???

<script src="js/system.js"></script>
<script>
  // get the anonymous scope
  System.import('js/main.js')
    .then(function() {
      // now we can get to the app and make a new instance
      System.import('app').then(function(m){
         let app = new m.App();
      })
    });
</script>
4
  • Yes that's how it's supposed to work. The first import loads the bundle just to pre-populate the module registry, there's nothing within the bundle telling which module should be executed, that's the purpose of the second import. Commented Jun 2, 2017 at 17:05
  • Thanks, but is there any way in which the app can start itself after being loaded? Most systemjs tutorials only mention import(js/main.js) and that seems to be enough...? Commented Jun 2, 2017 at 17:15
  • There's no way if js/main.js is a bundle containing several modules, in other words, it has several System.register() calls. I'd guess all the tutorials assume it's a single module, maybe built with rollup, or just unbundled and loading all other modules separately. Commented Jun 2, 2017 at 17:22
  • 1
    Thanks. The Typescript / SystemJS documentation says that you can bundle all modules in one .js file, and then use system-production.js to load everything. But apart from the fact that that doesn't work, it also doesn't mention how to instantiate the app.... it's kind of frustrating :) Commented Jun 4, 2017 at 11:23

1 Answer 1

6

After much head-scratching I found out the answer is more simple than expected: just load the bundle first as a regular .js file, and then you can import the app directly:

<script src="js/system.js"></script>
<script src="js/main.js"></script>
<script>
  System.import('app').then(function(module) {
    let a = new module.App();
  });
</script>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.