After the last post, where I briefly described how to setup mocha with ES6 (using traceur, a transpiler to working JavaScript) I couldn’t stop and had to prove, that getting it to run with on a real site was doable. It had it’s hurdles but voila it does work. See the github repo if you want to dive right into code.

Using Webpack needs an ES6 compiler

The latest I happily used to build CommonJS (node.js) style code and run it on the web is webpack. Since it comes with all possible loaders that one needs (JSX, ES6, etc.) there was not much thought I spent in what to use.

To get ES6 running in all (modern) browsers a transpilation step is required, which translates ES6 syntax into ES5 syntax that runs in all the browsers. For that I use traceur, which by features seems to be the most interesting one, more about this in a bit. Besides the translation of the code it does also need a runtime which brings all the boilerplate like class creation. I would like to have this all handled on the fly, I prefer not to have much to do with it. Please do just work.

As described in my last post I thought of using es6-loader for it. Quickly I realized I needed to hunt for something else. Why? Because I already started to use ES6 module syntax and wanted to keep going with it, just getting closer to the future sooner :). Have a look at it:

es6-loader uses the es6-transpiler, which states module syntax is not supported yet. Alright. That actually made the case for me to not use this project since I don’t want to run the tests with mocha but the production code with es6-transpiler, this does feel like pain coming up. So I went looking for a webpack-module that can do traceur. Even though I think it’s worth keeping an eye on es6-transpiler since the goals are just a bit different than those of traceur.

The hunt quickly revealed that there are two projects, after some stumbling I saw that actually one was just a pull request that got merged already. And in the end I saw that webpack-traceur-loader is what I need. One thing that worried me a little was that the current version of traceur it uses was 0.5x and traceur is already at 0.7x. But later I realized that all features work, so let’s go ahead. Here it is worth mentioning that the approach of mocha-traceur is quite cool, where it’s README says

Traceur is intentionally not included in this package so you can install your preferred version alongside Mocha Traceur.

which makes lots of sense as long as the API is compatible. If that’s not the case the user will have the failure and might be pissed.
And by this you can see that I already do run two different traceur versions. For the tests I am using the one I `npm install`ed and for production I am using the one wepback-traceur-loader brings along. I have to align the two to prevent bugs of the “works with the tests but not in production” kind – writing this on my virtual to do list.

Make an index.html and use ES6 for real

All the config is set up. Now I gotta try it in real life. So I added an ‘empty’ index.html to the example project. I just want to throw “works” into the body’s innerText. That serves as a good enough integration test for now.

Now I `npm install`ed the above discussed webpack-traceur-loader and enabled it. My `webpack.config.js` looks like this now (copied from the repo):

Now also the ES6 loader stuff works fine. And believe it or not, after `npm start` (which starts the webpack-dev-server) the site shows “works”. Find the revision online in the example project repo.

Include an external library, jQuery

Actually I am doing this because I want to convert the compass-map-app-kata to ES6 since I am tired of `var self = this;` and binding scopes, which imho is just blurring code and code’s intention with something that is missing in the language. But the app does also use jQuery to connect to all the simple DOM stuff. So next step here is to get jQuery into the game.

I want to see that the ES6 setup does not only work for my local files, but does also work when I integrate with external libraries. Of course I could go the easy way and include jQuery in the index.html, no-brainer. But I want to require jQuery on the server side too, so it gets bundled with the app.
I did `npm install jquery` and now inside my code I can use the nice `import jQuery from ‘jquery';`. Beautiful. Webpack doesn’t complain and it builds, it also shows me that it includes jQuery, as you can see below in line 22.

That was easy. Now let’s use jQuery in the code. So I add `jQuery(document.body).text(…)` so it prints ‘works’ on my site. But there is no ‘works’ showing up in the browser. Opening the console I see a ‘Uncaught TypeError: object is not a function’. What??? After a bit of debugging I find out that jQuery is an empty object. Ok, this must be the building part. What else can it be? So I start trying all possible things, going back to `var jQuery = require(‘jquery’)`. I also renamed all ES6 files to use `.es6.js` and configure webpack accordingly. I don’t like that, even though it very well shows what is ES6 and what not, but it is also there only because I just don’t know any better.
No solution really works.

Long story short. I saw that the `jquery.js` got modified after run through traceur and it then only exports `{}`. Well, that’s not what I want. So I have to exclude jQuery from traceur running over it. After fiddeling around, debugging into the webpack loader, learning lot’s from it and demistifying another piece of magic, I found the `exclude` parameter I have to pass to traceur in the `webpack.config.js`, as you can see below in line 9:

See in the last line that I also turned on `debug`, this outputs all the files that traceur handles, as you can see a bit further up in the webpack console output. Make sure NOT to see libs like jquery in there prefixed with `[traceur-loader]`, only the code you really want to be compiled.

Use it in real, compass-map-app-kata

The example project was born out of “I want to get it to work without any noise around it”. But of course the actual reason I investigated all that was another “bigger” app. The compass-map-app-kata, which is still called a kata, since it is that for me. And I am thinking of how to make this into a nice workshop :) since I see lots of potential in showing a real app using the DOM, doing it test-driven and sharpening the skills around TDD in a real ES6 web app environment.
The conversion from ES5 to ES6 of the compass app is a complete post on it’s own, which I might follow up on later. If you are interested, you can dive in by investigating the commits on the switch-to-es6 branch.
The short summary is: It does work. I am happy I did the baby steps in the example repo to focus on the small problems and really just worry about the actual problems, so I kinda applied the mikado method here, trying to find out the next missing piece in the chain, fixing it and switching back to the bigger scope.

Other/External services

The next step of getting this into production is to hook up with several external services for monitoring the health of the app. You can see that I added all kinds of badges in the README in order to test out those health-services. Let me quickly list what worked well with ES6 and where there are still bumps.

Travis CI

Integrating it with travis was no different than you do it with every project, of course it just does an `npm test` which requires a `.travis.yml`, so make sure they are there.
I also added codeship though I didn’t see how to make the project overview public. But it’s all green too (at least as of this writing) as you can see in the README badge.

Code coverage

I didn’t get a local istanbul for the coverage to work yet, there seems to be istanbul-traceur which seems to require gulp, I didn’t try that yet. I hooked up but seem to get no result from it yet. Not sure what I missed there. Hints welcome. It says that as soon as it passes in travis it will give me results, but didn’t yet.

Code quality services

I integrated codacy which is currently not doing much more than some simple code analysis, in this project it seems not to give any value, since it does not seem to understand ES6 syntax yet. You can see that by `LoC` and some other fields being empty. seems to do a real good job in detecting the ES6 files and understanding them, see the project files here. And it reports the files are in good health. I am glad for them :). Though the real value I get from it is still quite low. Actually I want to know more about my code, maybe this project is just way too small to really do too much wrong that can be found with static code analysis.


Overall I have to say the ES6 tool chain is already quite useable. And it is fun to move on with the language. Though I am still a little struggling with myself what will be the metrics for me for what to use when. After all I could write up the same for converting a project to LiveScript, CoffeeScript or TypeScript. They all get compiled to JavaScript, the big hurdle will be to see how well or bad either of those supports your workflow. There are multiple considerations that impact at least my workflow. It’s the following that come to my mind, and those I will have to keep an eye on when working with a language that is not “native”:

  • Does this new language really give me benefits or just satisfies my need to be up to date with the latest tech?
  • IDE support. First I need to have my IDE understand and highlight the syntax properly but very soon also refactorings and other tooling around it I need.
  • Setup work. Adding `–coffee` or `mocha-traceur` for running the tests bare a certain overhead to be considered.
  • Flow overhead when developing. Is there any disturbing compile time, longer test run time and/or more to setup with various options and addons needed?
  • Test report noise. How unreadable will my stack traces become, how much will this slow me down in my daily work? (Even though stack traces are always a thing one has to learn to read.)
  • External library/tool integrations. Is there any danger in integrating external tools and libraries, as talked about above with jQuery and the health-services.

Compiler, transpiler, whatever … you can replace each of the terms with whatever fits your preference.