If you've begun to embrace all the new features you get to use with io.js, your app will probably not run on latest node.js (0.12). const
and let
are only available when running node with the --harmony
flag and template strings don't work at all.
I had this problem recently with a little tool I built, gitclick. I was coding away under io.js and only after I released it to the public did I realise that it is not compatible with node.js. At first, I dismissed the issue and proposed everyone to upgrade to io.js. A day later I must say that it was pretty naive of me to think that anybody would upgrade just to use my tool.
I did not want to rewrite my entire app to work with ES5 so I decided to come up with a different solution: running my app through Babel, but only if the user is not on io.js (to retain the best performance there).
It really is simple to get this setup, but I created a little demo project anyway. Here is how it will work:
say-hello
Hello io.js
Hello node.js
Check out the GitHub repository for quick access to the "solution".
package.json
{"name": "say-hello"}
Terminal:
$ npm i is-iojs -S
bin/say-hello
#!/usr/bin/env node'use strict'const iojs = require('is-iojs')const engine = iojs ? 'io.js' : 'node.js'console.log(`Hello ${engine}`)
Above code would not run on the latest version of node.js because it is using features of ES6 that aren't supported there yet. This is why, we will use Babel to compile the code down to ES5 before running it on node.js. So first, install Babel as well:
Terminal:
$ npm i babel -S
Next, create a wrapper-file that runs our app through Babel if we are on a node.js platform.
bin/say-hello-harmony
#!/usr/bin/env node'use strict'var iojs = require('is-iojs')if (!iojs) {require('babel/register')({ ignore: /say-hello\/node_modules/ })}require('./say-hello')
There is an interesting little thing about this line and the ignore
option:
require('babel/register')({ ignore: /say-hello\/node_modules/ })
Babel ignores files within any node_modules
folder by default. If you npm install
a module globally, it usually goes into a directory like /usr/local/lib/node_modules
. Therefore, without the above line, Babel would not register properly because your module itself is inside a node_modules
folder when installed globally.
It took me a few hours to figure out why require('babel/register')
would work if I npm link
a module but not if I'm installing it globally via npm. Now I know and you do too! :)
Now we're almost done. Just simply make sure that correct bin-file is specified in your package.json
.
package.json
{"name": "say-hello","bin": "bin/say-hello-harmony","dependencies": {"babel": "^5.1.10","is-iojs": "^1.1.0"}}
Next, enter the following command to make the say-hello
command available in your terminal.
Terminal:
$ npm link
That was it. If you're using a version manager like n (n is awesome!), you can easily test if everything works:
$ node -vv0.12.2$ say-helloHello node.js$ n io latest$ node -vv1.7.1$ say-helloHello io.js
Hi, I’m Max! I'm a fullstack JavaScript developer living in Berlin.
When I’m not working on one of my personal projects, writing blog posts or making YouTube videos, I help my clients bring their ideas to life as a freelance web developer.
If you need help on a project, please reach out and let's work together.
To stay updated with new blog posts, follow me on Twitter or subscribe to my RSS feed.