Use some ES6 in CLI apps

What useful ES6 features can we use right now?

I have been playing 1,2 with some ES6 code, but always via Babel or Traceur. Yet I miss having code running straight from its source, without any large dev dependencies or transpiling steps.

Can we use some of the ES6 features right now on the most popular versions of Node (0.12 and 4)?

Turns out we can, and it is pretty simple. It is so simple, that we can probably avoid very long discussions on how to publish ES6 modules, at least for today.

The main idea is:

Just start using the basic ES6 features, like const and arrow functions in your code. Node 4 and 5 will play nicely right away, and Node 0.12 will handle it just fine if you add --harmony to the CLI shebang line.

That is it. Here is the experiment. Let us take a few features that I like the most right now: const, let, arrow functions, string templates, default arguments, Object.assign and the new string methods (like startsWith). Do they work under Node 0.12 and 4? Well, some do by default in v4 and even work in v0.12 under --harmony flag.

I write a lot of NodeJS CLI applications, so adding a flag to the shebang line is no problem. For example, a quick NPM script runner npm-quick-run has the following shebang in its bin script

#!/usr/bin/env node --harmony
'use strict'
const quickRun = require('..')
let help = [
  'USE: nrun <npm script prefix> <script arguments>',
  '\t"nr t" === "nrun t" === "npm test"',
  '\t"nr m -w" probably will find "npm run mocha -- --w"'
].join('\n')

This code runs as expected under Node 0.12; even better, the --harmony command line argument is silently removed by the Node runtime. If we print the arguments, it is not there.

$ node --harmony -e "console.log(process.argv)" "foo"
[ 'node', 'foo' ]

So all code that worked before adding --harmony should just continue working. We do need to set the strict mode, otherwise Node 0.12 cannot parse the let keyword.

Testing available features

To figure out what can be used, I plainly ran a few code samples. If they compile and execute - we are in business! The following tests worked right away

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
'use strict';
console.log('node version', process.version);
function testConst() {
const foo = 'foo';
console.assert(foo === 'foo', 'const foo is wrong', foo);
console.log('const is working');
}
function testLet() {
// need 'use strict' for "let" to work
let foo = 'foo';
console.assert(foo === 'foo', 'let foo is wrong', foo);
console.log('let is working');
}
function testArrows() {
var doubled = [1, 2].map(x => x*2);
console.assert(Array.isArray(doubled), 'returns an array');
console.assert(doubled[0] === 2, 'doubled first number');
console.log('=> is working');
}
function testBinary() {
console.assert(0b111110111 === 503, 'binary is not working');
console.assert(0o767 === 503, 'octal is not working');
console.log('binary and octal notation is working');
}
testConst();
testLet();
testArrows();
testStringStartsWith();
testBinary();
/*
$ node --harmony index.js
node version v0.12.7
const is working
let is working
=> is working
string startsWith() works
string endsWith() works
binary and octal notation is working
*/

ES6 features that are not working in Node 0.12

Testing the other ES6 features are tricky. First, one cannot even test the template literals directly - the code would not even compile. One has to resort to all sorts of tricks typically using eval. But by running pieces of code manually, I have found that the features I wanted the most where not available. Here is the short list with possible work arounds I use

As you can see, pretty much everything might be just a library call away, except the Lodash templates do NOT support multi line strings like template literals; and of course no ES6 modules.

Conclusion

Using these little ES6 gems makes me more productive. And the same code can work in the browser - one needs to transpile it anyway!

What about other CLI tools that I do not control, but often use, like Mocha? Well, when I run an NPM script that calls a local Mocha install, I can use --harmony flag too, see the Mocha bin script.

Finally, a shameless plug: whenever I need to lookup ES6 syntax or semantics, I use manpm CLI tool.

Updates