I’m currently in the process of building a new web application. I want to use a module loader. I have used Required as a AMD loader, but with ES2015 (ES6) around the corner and supports module loading, I would like to use something that is somewhat future proof. So, I’ve decided to investigate SystemJS.
To learn SystemJS , I wanted to create a very simple application with no frills and uses ES5. Once I have this figured out, I will start using ES6 and/or TypeScript.
SystemJS
SystemJS is a universal module loader. It can load modules synchronously or asynchronously. In this post I’m going to load a very simple global module dynamically. SystemJS can load these additional modual formats:
- esm: ECMAScript Module (previously referred to as es6)
- cjs: CommonJS
- amd: Asynchronous Module Definition
- global: Global shim module format
- register: System.register or System.registerDynamic compatibility module format
Assumption of Reader
I assume the reader has the following knowledge
- Some knowledge node.js and npm
- JavaScript
- Chrome Developer Tools
I assume that since you want to learn about systemJS, which is a more advanced tool, that you understand NPM and how to install
libraries using package.json. I also assume you know how to create a server to run the examples on. In this example, I’m using HTTP-Server that I installed using NPM.
Tools and Version I used
Here’s the structure of the application
- package.json: is used to install systemJS
- .gitmore: can be ignored. It’s used with Git source code repository.
- node_modules: where npm installs systemJS
- main.js: the module to be dynamically loaded and execute by systemjs
All source code can be found here:
Example without using systemJS: https://github.com/BarDev/Learning-SystemJS/tree/b.1.0
Example using systemJS:https://github.com/BarDev/Learning-SystemJS/tree/b.1.1
First run “npm install”. This will look in package.json and find dependencies to install. The only client dependency that is required is systemjs.
Let’s now display a very simple HTML page. Here’s the code:
Let’s do a a sanity check to validate that the server is working. You can use any server. I have decided to use http-server for it’s simplicity and no bloat. Below in the images, you will notice I install http-server globally, and then ran it by just call “http-server”. I then load the page using the port that http-server provided.
Everything should be working now.
Let’s create a module. I’m using the term module somewhat loosely here. Since the code is in a separate file, systemJS will treat it like a module. Here I’m using the Revealing Module Pattern.
Let’s create a new folder called app and add the file main.js. Here’s the code to include in main.js.
We aren’t using systemJS and not doing module loading yet, but we will soon. For the time being, let’s see how main.js is loaded.
Add a reference in index.html to main.js. This can be added in the <head> element. Then add the script that calls the domUpdater after the last div. The script must be after the div, because of how the HTML page loads and is executed.
Lets run the web page and see how the modules are loaded. In the image below you will see that in Chrome Developer Tools, I added a breakpoint in the index.html. This allows me to see what files have been loaded in the network tab. As we can see the main.js file has been loaded. The main.js file is loaded as soon as the page is loaded. Imagine if you had 20 files that need to be loaded. Bundling can take care of this somewhat; but what if you had multiple bundles and not all bundles are needed when the page loads?
Now let’s do some module loading using systemJS.
In index.html, remove the script in the Head that is referencing main.js. Also remove the script after the div that is calling domUpdated
Now we need to add the systemJS library and load mainJS using SystemJS.
In index.html, reference the system.js file in the <head>.
Now, refresh the page and put a breakpoint on the console.debug, and refresh again. If you look at the Network tab in Chrome Developer Tools, you will see that main.js has not been loaded yet.
Continue the application and you will see in the network tab that main.js is loaded dynamically in the process..