Loading JSON files with SystemJS module loader

I really hate this mess on JavaScript modules. We have AMD, CommonJS or UMD to support both. Then ES6 came into the game. But what about .json files on browser? There are different ways to load them and not all libraries support them! Your module loader should be sophisticated enough to handle this.

In this post, I am going to talk about SystemJS and how it simply loads files in the browser, other than .js files, like text or JSON, especially from third party modules, without driving you nuts!

Let’s assume you are using a third party library and this library needs to load some JSON files. And the code from the third party library is going to be loaded into the browser, not in Node.
As a reference, let’s use i18n-iso-countries, which is one of my favorite libraries. In its source you will see something like this:

var codes = require("./codes.json");
var data = {
    "ar": require("./langs/ar.json"),
    "cs": require("./langs/cs.json"),
    "de": require("./langs/de.json"),
    "en": require("./langs/en.json"),
    "es": require("./langs/es.json"),
    "et": require("./langs/et.json"),
    "fi": require("./langs/fi.json"),
    "fr": require("./langs/fr.json"),
    "hu": require("./langs/hu.json"),
    "it": require("./langs/it.json"),
    "nb": require("./langs/nb.json"),
    "nl": require("./langs/nl.json"),
    "nn": require("./langs/nn.json"),
    "pl": require("./langs/pl.json"),
    "pt": require("./langs/pt.json"),
    "ru": require("./langs/ru.json"),
    "sv": require("./langs/sv.json"),
    "tr": require("./langs/tr.json"),
    "zh": require("./langs/zh.json")

Well, if you try and use this library in the browser, without a JSON plugin, you are going to lose. SystemJS module loader cannot find these files with that funny “.json” extension, you need to let it know about them. But how?

The answer is plugins. This awesome module loader supports several plugins and loaders. Look here, at its Github repo. There is support for JSON, exactly what we are looking for!

But how is this going to help us? Well, using this loader, SystemJS will be able to understand these require call. But this doesn’t come for free. In SystemJS you need to postfix the call with a !json text.

Something like this:

var codes = require("./codes.json!json");

But if you do that, you mess with the third party library and you shouldn’t. Yes that is true. That’s why, SystemJS has this loader, to postfix the require call with that magic little text!

Just add this loader into your meta configuration like so:

var config = {
    map: map,
    packages: packages,
    meta: {
        "*.json": { "loader": "json" }

And that should work. Just that.

And what about Webpack, or AMD? These fellas want the !json as prefix. Well, there is configuration for that as well, you can just enable it globally, setting the pluginFirst to true.

System.config({ pluginFirst: true });

Same applies for other types of files, like text or CSS, etc. Again, check the available loaders for SystemJS. You may wish to add yours to load some kind of file.
Also take a look at SystemJS docs on plugins loaders in order to learn how to use the existing loaders.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s