Choose ES6 modules Today!

es6_modules_header

I am done using outdated and non-standard module solutions. I have been waiting a long time for ES6 modules and I want as much ES6 as I can get…today! I want all of this without having to choose, or without being forced to choose, one specific packaging registry over another. So, let me get straight to the point.

I believe when starting a new front-end development (i.e. a SPA or native browser application) project, you should stop doing the following.

  • using Require.js or Browserify to load modules and manage dependencies.
  • using one specific repository of packages alone (i.e. npm alone) tied to one specific non-ES6 module format (i.e. CommonJS alone).

Stop that and start:

  • Using ES6 package control syntax (aka ES6 modules) and the module loader (i.e. System.import) for importing, exporting, and loading modules.
  • Using jspm.io to load any type of third-party module (i.e. ES6, AMD, CommonJS, UMD, global) from any registry (i.e. npm, Bower, Github) by way of ES6 modules syntax and System loader (polyfill provided by SystemJS & es6-module-loader)

You want to do this because building a standards-compliant and future-friendly application, while not tightly coupling yourself to AMD or CommonJS (and friends) and their respective package managers, just makes good, damn sense. Why? Because jspm.io and SystemJS favor ES6 module standards and they’re agnostic when it comes to a specific, non-standard module format of the past or a specific repository of packages alone.

Use ECMAScript 6 Modules Today

By using jspm.io you can make use of the official JavaScript module control system (and its syntax) today – all while not having to wait for older modules to be re-written or having to limit yourself to one particular module format or package manager. In other words, you shouldn’t have to care from where a package comes and in what format it’s being provided.

The ideal, and yes we have arrived, is to just use ES6 modules and let a tool like jspm.io sort out all of the ugly details as it pertains to non-es6 modules from multiple endpoints. Not to mention, by using jspm (and a ES6 transpiler like traceur or Babel) you get most everything that ES6 offers, not just modules. Writing ES6 code in your ES6 modules sounds good, right!

In the remainder of this article I am going to show an example of using jspm.io in your architecture so that your development code (production gets compiled to ES5) uses ES6 module syntax to potentially load any type of module (e.g. ES6, AMD, CommonJS, UMD, and global modules) from anywhere (e.g. npm, Bower, and Github).

Getting Setup with Node.js, Browser-sync, and jspm

First things first, we have to set up a local Node.js development environment with some Node.js packages. To do this, follow the five steps below (Note: I’ve provided a video showing the steps that are detailed below and runnable code at Github. Watch the videos, read the steps, play with that code in that order):

Step 1. Install Node.js. Just go to https://nodejs.org/ and get an installer.

Step 2. Create a local folder named dropdown and a package.json file in that folder by running npm init. As the npm doc’s describe, ‘npm init’ “will ask you a bunch of questions, and then write a package.json for you.”

Step 3. npm install browser-sync --save-dev. We will need a server and something that alleviates wrist pain from clicking reload in a browser.

Step 4. Create an index.html in a src directory then write a browser-sync command that is stored as a script to be run by the npm CLI. One could Grunt or Gulp it up, but let’s keep things simple. After all, most task running these days is done because one is too lazy (as it should be) to remember or type out tool specific terminal commands.

Step 5. npm install jspm/jspm-cli -g and npm install jspm --save-dev. This will install all the jspm packages needed to use jspm globally and locally (It is advisable to locally install jspm in additional to globally installing it to lock the version of jspm for a specific project).

Understanding the Stack

At this point, if you are following along, everything is set up for jspm development. But you might not exactly understand the stack you just set up. Let me break it down for you in more detail.

Node.js

Node.js is a JS platform for running JavaScript applications. You installed two NPM packages/applications, browser-sync and jspm, that will run locally to help you with development.

npm

npm is the Node.js package manager and is installed by default when you install Node.js from an installer. It is most helpful for developing Node.js applications. However, a lot of people attempt to use it, and desire it, to also be the package manager for the web/browser platform.

package.json

This file is created for you after running npm init and answer some questions. This JSON file holds all the metadata for a Node.js project and handles the details around the project’s dependencies. Many of the npm CLI commands (e.g. npm install) use values defined in the package.json file. The npm run serveit is an example of a NPM command that uses a value found in the package.json file.

jspm

Think of jspm as a web/browser package manager, similar to Bower except jspm strives to sit over the top of all other package managers (including npm) and offers a module loader (i.e. SystemJS) that understands the installer. Its goal is to allow you to load any type of module from any registry. By using jspm, you are favoring a package manager that is not trying to play favorites. It is simply giving you the means to install any package from most any endpoint, while abstracting away module differences and repository endpoints, until which point everyone is using ES6 modules.

By default, jspm does offer official support for installing packages/modules from the npm registry and GitHub. Also, jspm offers its own small registry (a simple GitHub repo) that contains shortcut names used by the jspm CLI (e.g. jspm install jquery maps to jspm install github:components/jquery) to install package from npm and GitHub. Of course, any endpoint can be setup, npm and GitHub are just the defaults.

Additionally, by using jspm it is possible to pass overriding meta details for a package to the underlying SystemJS tool during installation. This is actually the most powerful part of jspm and I encourage you to think carefully about the power provide by jspm for overriding package.json configuration values during installation from the CLI or as part of the source of the package itself.

The value of jspm does not stop with the role of a package manager. By installing jspm you get SystemJS, a universal dynamic module loader and dependency manager built on top of the ES6 module loader polyfill all driven by Tracuer or Babel.

By using the jspm CLI to install packages, you are broadly accomplishing/abstracting the following processes.

  1. Installing a package/module from a registry, like npm, or some endpoint like GitHub.
  2. Configuring the config.js file used by SystemJS to load modules and bundle those modules for production
  3. Compiling ES6 to ES5
  4. Updating the package.json file with metadata used by jspm and SystemJS.

browser-sync

This Node.js application provides a web server, to server your app, and browser reloading when any of your local development files change.

Configuring jspm For Development

Hopefully, my summaries describing the stack have shed some light on jspm and its role in the stack. Next, I will show you how to configure jspm for development.

Step 1. Create a config.js by running $ jspm init. This will ask you a bunch of questions:

jspm_init

Based on the above questions and answers a config.js file will be added to the public folder (i.e. src).

Step 2. jspm install text css json SystemJS plugins. These three plugins let you use ES6 importing to bring CSS, JSON, and plain text strings into the scope of a module. Of course, the CSS plug-in doesn’t really bring CSS into JS. Instead, it does what you might think, i.e. adds CSS to the HTML page the old fashion way by updating the HTML page with the correct <link href="">.

Step 3. Create a .jshintrc and startup.js file. I’m adding the .jshintrc file (i.e. {"esnext": true} ) so that JSHint will stop yelling at me about ES6 syntax. The startup.js file will be the first module that runs to start up our application.

{
  "esnext": true
}

Step 4. Include system.js, config.js in the index.html file using <script> elements and the startup.js file using System.import.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <script src="/jspm_packages/system.js"></script>
    <script src="/config.js"></script>
    <script>
        System.import('./startup'); //note no .js on this file
    </script>
</head>
<body></body>
</html>

Writing ES6 Modules Using JSPM

At this point we have everything set up and configured to write ES6 code and use ES6 modules. So let’s take it for a spin by installing Kendo UI and Bootstrap and using them to create a simple DropDownList widget from a Kendo UI template and JSON data.

Step 1. ‘jspm install kendo-ui bootstrap’. This will read the jspm registry and install kendo-ui and bootstrap from the paths stored in the jspm registry. Note that it will also install these packages using the kendo-ui and bootstrap overrides for GitHub.

Step 2. import the Bootstrap CSS and System.import the dropdown module into startup.js (Note my use of ES6 all over the place).

import 'bootstrap/css/bootstrap.css!';

System.import('dropdown/dropdown').then(
    dropdown => console.log(dropdown.dropdown.value()
));

Step 3. Create a dropdown folder and add a dropdownTemplate.html containing a Kendo UI template and a dropdownData.json file containing the data for the dropdown widget.

Template:

ContactName: #:data.ContactName#, CustomerID: #:data.CustomerID#

Data:

{
    "CustomerID": "ALFKI",
    "ContactName": "Maria Anders",
    "CompanyName": "Alfreds Futterkiste"
}, {
    "CustomerID": "ANATR",
    "ContactName": "Ana Trujillo",
    "CompanyName": "Ana Trujillo Emparedados y helados"
}...]

Then code the dropdown.js module using ES6 syntax and SystemJS plugins to create a Kendo UI dropdown widget when dropdown.js is imported.

kendo_widget

//JS
import kendo from 'kendo-ui/src/js/kendo.dropdownlist.js';
//template
import dropdownTemplate from './dropdownTemplate.html!text';
//data
import dropdownData from './dropdownData.json!';
//css
import 'kendo-ui/styles/kendo.common-bootstrap.min.css!';
import 'kendo-ui/styles/kendo.bootstrap.min.css!';

const view = $('<div class="panel panel-default" style="margin:50px"> <div class="panel-heading">Select:</div> <div class="panel-body"><select></select></div></div>').appendTo('body');

const dropdown = new kendo.ui.DropDownList(view.find('select'),{
    template: kendo.template(dropdownTemplate),
    dataTextField: 'ContactName',
    dataValueField: 'CustomerID',
    dataSource: dropdownData
});

export {dropdown};

Is this crazy awesome or what? ES6 modules today without leaving behind ES5 only browsers!

Bundling

But wait, you want more? Did I hear you say bundle? No problem. Let’s do that too.

Using jspm, bundling will not only bundle all of your modules together into one build.js file (with a .map file), it will also inline all of your CSS imports into the HTML page. The command jspm bundle module1 + module2 --inject will update the config.js with bundle configurations. To un-bundle when using --inject you’ll have to un-inject (i.e. remove bundle settings from config.js) the build files to go back to development mode. This is done by running, jspm unbundle.

Conclusion

I have laid the foundation for what I think should be the starting point for most any JavaScript web application project today. A lot of the details would still need to be defined and configured for a real solution, but the basic foundation has been discussed in this article – mainly, how to use ES6 modules while not hitching yourself to non-standard module solution or one repository of packages.

If you like what you have seen in this article, go get the code from GitHub and use it to learn or use it as a boilerplate to start your next JavaScript project using ES6 modules. At the very least, no matter how you do it make sure you are using ES6 modules moving forward (e.g. Angular 2 uses SystemJS & Aurelia uses jspm.io).

So, start using jspm.io today for ES6 modules, and grab the open source Kendo UI Core for a rockin’ UI.

Build responsive HTML5 apps. Fast.

Comments

  • Owen Densmore

    So: does this simplify workflow? Like can jspm basically replace bower, anyway, and maybe simplify npm use?

    • I think so. But let me explain. jspm sits over all endpoints (github, bower, npm) or any endpoint you want. Use it with anything. Now you might think that complicates workflow, but I personally think it simplifies it. I want to choose code from any endpoint. And I want my package manager to be friendly with my loader by design. And I want all of that to be ES6 focused. So, not only do I think that it simplifies everything, it also attempts to be the most future friendly solution.

  • alex

    I really want to like jspm but hitting jspm.io and watching a spinner just doesn’t seem great. If it’s representative of how long it will take my page to be responsive it didn’t inspire confidence. Have you had better experience or does the production packaged versions work better for you?

    • Dominic Chambers

      jspm adds no delay to app start-up times whatsoever. That spinner will most likely be a consequence of how the web-site has been designed.

    • Odd. I’m not experiencing that on the jspm.io site. You might let Guy know via a Github ticket. https://github.com/jspm/jspm.io/issues

      • alex

        Thanks for the advice, I did a quick network trace and it seems some of the dependencies are slow to load sometimes (showdown) so it could be more a factor of where the assets are being served from combined with my spotty network connection at work/mobile. I’ll have to give it a try from different locations and see if I can reproduce and if so I’ll raise a ticket.

        Thanks for the article and looking forward to trying out jspm instead of browserify!

  • Owen Densmore

    Thanks Cody. Time for me to start using jspm for sure.

    Now if only it could be used for *dev* dependencies!

  • Pingback: WebPack For Visual Studio Developers - Telerik Developer NetworkTelerik Developer Network()

  • No mention of webpack?

    • Nope. ES6 Module all things! 🙂

      • Stas

        Hi! Sorry for my English.
        Webpack works well with es6-modules via babel-loader.
        Why you are so categorical? 🙂
        Webpack is more powerful bundler with many features.

        • I didn’t mean to be. At this point, anything that gets you ES6 modules is amazing.

  • Owen Densmore

    Boy have I drunk the kool-aid! Watch the videos, followed your tutorial (and a few others), built a repo w/ jspm .. and its spooky easy, near magic.

    Thus far, the biggest problem I’m having is “legacy” webgl libraries. I’ve had to cherry pick on github like this:

    jspm install webgl-debug=github:KhronosGroup/WebGL -o “{main:’sdk/debug/webgl-debug.js’}”

    .. which worked but hauled over 66Mbytes!

    I haven’t found the docs to be as helpful as I’d like for this sort of thing. I’d love a way to install just a http://foo/bar.js file as a module, but haven’t been able to do it .. do you know how? Or where the right docs would be? Gitter wasn’t much help, alas, likely poorly stated question.

    • Checking out a git project will grab that entire project, as well as the full history for all branches that you are tracking… This isn’t the same as what gets loaded into the browser, which should be just the resources in question…

      Beyond this, In general, you’ll want to add node_modules/jspm_modules/bower_modules to your source control’s ignore file (.gitignore for example). As you generally want to ‘jspm install’ or ‘npm install’ when you first checkout. In generall npm/jspm packages should be less kitchen sink than their github related counterparts, and ymmv.

  • Pingback: ES6 and a future-ready project | ('event', handler)()

  • Trevor

    Hi, I was running through your tutorial but I encountered an error during the “Writing ES6 Modules Using JSPM” step

    warn Error on download for github:twbs/bootstrap, retrying (1).
    Error: CERT_UNTRUSTED
    at SecurePair. (tls.js:1381:32)
    at SecurePair.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:980:10)
    at CleartextStream.read [as _read] (tls.js:472:13)
    at CleartextStream.Readable.read (_stream_readable.js:341:10)
    at EncryptedStream.write [as _write] (tls.js:369:25)
    at doWrite (_stream_writable.js:226:10)
    at writeOrBuffer (_stream_writable.js:216:5)
    at EncryptedStream.Writable.write (_stream_writable.js:183:11)
    at write (_stream_readable.js:602:24)
    at flow (_stream_readable.js:611:7)
    at Socket.pipeOnReadable (_stream_readable.js:643:5)

    • Trevor

      Fixed.
      It turned out that it was the version of node I was using. Updating my node version (on windows) to v0.12.4 fixed it for me

  • Jon Cuthbert

    Thanks Cody. I have a question about JSPM. Suppose you want to create a unique bundle for multiple templates and have it also create a bundle with the common shared dependencies of each template. Browserify has “factor-bundle” and Webpack has “CommonsChunkPlugin”. Does JSPM have anything for this?

  • Personally, I’m not really liking parts of your example for the same reason that I don’t care much for webpack. I currently use BabelJS to transpile (and in cases combine with Browserify). What this allows me to do is use the exact same code for client and server rendering via Flummox+React or similar workflows. Not to mention support for async/await syntax, and other to be formalized sugar.

    Beyond this is that in order to even get jspm (or Bower for that matter), I have to install node/npm anyway, I’d just assume stick to that, which also supports the use of git/github for modules. Not to mention the PFM used for loading CSS doesn’t really meld well in an isomorphic context.

    All in all, I’d rather stick with npm (because it’s already there, and easy enough to use)… if you are bundling anyway, there are other means to the end of using ES6 module syntax while still being able to support client+server rendering and logic. I’d really much rather see people expressly *not* support bower and jspm in favor of vanilla npm, because it doesn’t make much sense to use one package manager to install another, with a significant overlap of functionality, and features that lose other parts of functionality.

    • So. RIght. I agree. The important part is that you are ending/using ES6. And in fact, I don’t care how you get there as long as you get there and stop using non-standard JS. That is the important part. As for npm v.s. X. As of today, I’ll take an abstraction over all of them (and especially one that is made to work with the loader) instead of choosing one. Simply because of the freedom I get with that strategy. But for sure, that won’t jive with everyone’s project or brain. Fair point.

  • Pingback: Six Steps for Approaching the Next JavaScriptTelerik Developer Network()

  • Pingback: Choose ES6 modules Today! -Telerik Developer Network | Attack Tech()

  • Jacob

    Thanks for this article. I tried installing Kendo Pro using:
    sudo jspm install kendo-ui=bower:https://bower.telerik.com/bower-kendo-ui.git

    It installs, but then my “serveit” localhost:3000 request fails due to this browser error: XHR error loading bower:https://bower.telerik.com/bower-kendo-ui.git@2015.2.813.js

    Are you able to install Kendo Pro in jspm?

  • Pingback: Hail, Babel! The Transpiling Overlord -Telerik Developer Network()

  • Ciaran O’Neill

    Do you know how I can use Kendo professional with jspm? Pro isn’t on npm or
    github. I always download from telerik.com as we have devcraft complete and
    have kendo.all.js as a ‘static’ resource in a vendor scripts folder. Any idea how I can
    get this to work with the jspm workflow?

    • Jacob

      I posted the same question in the forums, and got this response:
      http://www.telerik.com/forums/install-kendo-ui-professional-package-using-jspm

    • At the very least you can just drop the pro source code into your project and use systemjs to import anything you want. Does that make sense? jspm is just a tool to download public packages. You can of course, use systemjs to include anything you want. Or, am I pointing out the obvious?

      • Ciaran O’Neill

        That’s exactly the route I’ve gone down. I’m using System.import to bring it in as a dependency in my html page. I was hoping to use it in a TypeScript file using an import * as kendo from ‘path to kendo’ but I didn’t have any success doing it that way – it was never loaded or jquery was not loaded first (race condition due to latency perhaps)

    • brownieboy

      Telerik has just said that it has an npm version of Kendoui Pro in the works, although there’s no date announced yet. See this thread: http://www.telerik.com/forums/kendo-ui-professional-npm-package

      In the meantime, you can install Kendoui Pro from Bower. It’s a pain, but it does work. Basically, you install nodejs/npm and then use npm to install bower, i.e.:

      npm install bower –save-dev

      So yes, you install one package manager from another one!!!

      Once you have Bower installed, follow the Telerik instructions below to install Kendoui Pro. You’ll need your Telerik login ID and password to install it that way.

      http://docs.telerik.com/KENDO-UI/intro/installation/bower-install#install-kendo-ui-professional-bower-package

      Note: Kendoui Pro is a big download, and a very slowwwwww one for me: about 20-30 minutes. Once it’s done once though, it’s cached in your home folder somewhere. So the next time you install it this way, it will actually get pulled out of that cache and will only take a few seconds. (You still have to enter your Telerik ID and password though.)

  • Jedd Ahyoung

    You guys talk a big game, but your npm module (kendo-ui-core) isn’t configured for JSPM. Thus, when you try to install it, jspm is unable to access the script as there’s no “main” configuration. I’ll be submitting a jspm repository override for this. Hopefully, you guys will update your package.json…

    • Only the bower one is official. The npm is not. Thus, you have to use the jspm repo version pointing to the bower endpoint.

      i.e. $ jspm install kendo-ui

      Also, a bug got fixed that will allow systemJS to work with kendo-ui AMD. You can override the jspm.io registry when installing with the following jspm install command and flag.

      $ jspm install kendo-ui -o “{‘main’:’src/js/kendo.core’,’format’: ‘amd’,’shim’: {‘src/js/kendo.core’: {‘deps’: [‘jquery’],’exports’: ‘kendo’}}, ‘dependencies’: {‘jquery’: ‘github:components/jquery’}}”

  • brownieboy

    Good article, and it got me thinking, as all good articles should!

    I got JSPM working on a small test project, as per your instructions. I found it to be too many moving parts for my liking though. I especially don’t like the need for three package managers – not only npm and JSPM, but also Bower if you need the Pro version of Kendoui.

    Being a major Reactjs fan, I was already somewhat familiar with Webpack. But I didn’t realise that it could also import AMD as well as CommonJS modules.

    I now have Webpack working on a test project to pull in Kendoui Pro packages (AMD compliant) into ES6 modules. With webpack-dev-server for development. I’m still using Bower to load Kendoui Pro, as the latter’s not on npm (only the open source version of Kendoui is). But it’s npm for everything else.

    I can share my config if anybody’s interested.

    • Bruce Denham

      I’m very interested in how you got Webpack working to pull in Kendoui Pro packages into ES6 modules. A config file for this would be helpful. Thanks!

  • Hey Cody, Loved this article. Hesitant on JSPM until recently because change in a small shop is time-expensive; but after bouncing around between Browserify, RequireJS and more recently Webpack over time and continuing to be of the ‘meh’ community where Bower/Npm gave me all I needed, provided a verbose, yet transparent, build process – I finally took a deep dive into JSPM over holiday and finished Wes’s Pluralsight course on JSPM, which was incredibly well done and insightful. Fell in love with it. Jspm, SystemJS and the Es6 modular loader is definitely amazing.

    But I don’t build web apps ( by its commonly accepted definition ). I build websites, and sometimes they act like SPAs and sometimes they dont. Definitely tackle a lot of the common tasks daily like bulky ajax requests, state management, view updates, etc.

    In that regard, using JSPM to build an sfx and let it rip is a great workflow, but I feel like I’m bypassing all of its benefits. I’m used to concatenating everything that makes sense for an average user, and taking the initial hit on first load. But with JSPM the primarily benefit is the authoring process using ES6 modules ( which was my #1 motivator for JSPM ). That said, my projects would get some, but little benefit from dynamic module loading.

    My question for you is, would you say that using JSPM and generating sfx builds is a stronger bet give that all code would be written in ES6. Or for ‘websites’ ( with lots of global imports ) is it just better to stay the course and rely on build tools ( gulp ) and then plugin whatever transpilers I may need?

    I spend a good amount of time on the internet and I think this question is a big elephant in the room when it comes to building websites that are highly dynamic but don’t use angular or react.

  • I had the following error: error: XHR error (404 Not Found) loading jspm_packages/npm/babel-core@5.8.34.js. Setting an empty baseUrl (instead src) removed that error.

  • Pingback: ES6 imports - what does the exclamation mark mean? - HTML CODE()