This is a follow-up to the "Making your io.js command line apps compatible with node.js" post. While the previous article deals with running your ES6 command line app through babel-node
when on a node.js platform, this article deals with how you setup your project in a way that an ES5 version of your app is automatically compiled and used when on a node.js platform and the original ES6 version is used on an io.js platform.
This has several advantages, such as not having to require Babel in your production dependencies. Also, performance is better on ES5 platforms when the files are pre-compiled and it is more trivial to run the tests on ES5 platforms if they are also written in ES6.
We will be using the say-hello app we built in the "Making your io.js command line apps compatible with node.js" post. You can find the version for this article on the master branch.
This is how I setup my ES6/ES5 hybrid command line app gitclick:
es5/bin/test/main.jssrc/bin/test/main.jsnode_modules/main.jspackage.json
Some observations:
./main.js
is the main entry point. Here, we either load ./src/main
or ./es5/main
./es5/
is an ES5-mirror of ./src/
and will be built with Babelnode_modules
and package.json
live at the project's root$ npm i is-iojs -S && npm i babel -D
This command will install is-iojs
as a normal dependency and babel
as a development dependency. We only need Babel to build the ES5-version before we publish our project to npm but our project will not require Babel at runtime.
"scripts": {"build": "mkdir -p es5/bin && babel src/bin/say-hello --out-file es5/bin/say-hello","prepublish": "npm run build"}
build
is the script that actually compiles our app down to ES5babel src --out-dir es5
would compile everything in our src
directoryjs
extension, so we have to run babel src/bin/say-hello --out-file es5/bin/say-hello
to compile our binmkdir -p
to make sure the directory existsprepublish
makes sure that this build
is always run before we publish our package to npmWith all the meta-stuff setup, let's build our little say-hello app. You will be able to run say-hello
from your terminal to either display "Hello io.js" or "Hello node.js", depending on which platform you are on.
#!/usr/bin/env node'use strict'const iojs = require('is-iojs')const engine = iojs ? 'io.js' : 'node.js'console.log(`Hello ${engine}`)
Now, let's make sure that this app runs on both platforms:
Depending on our platform, we will either direct our user to the ES6-bin or the ES5-bin:
#!/usr/bin/env node'use strict'require(require('is-iojs') ? '../src/bin/say-hello' : '../es5/bin/say-hello')
Don't forget to declare the path of your bin:
"bin": {"gitclick": "bin/gitclick"}
And make sure that the file is executable:
$ chmod +x bin/say-hello
That was pretty much it. Check out the code in the GitHub repository for this little demo.
I didn't implement this in the say-hello
demo but this is how I test ES6 and ES5 versions for gitclick.
To test your app when compiled to ES5, you can use the following scripts:
"scripts": {"test-es6": "mocha src/test --recursive","test-es5": "mocha es5/test --recursive","test": "if [ \"$(node -e \"console.log(require('is-iojs'))\")\" = \"true\" ]; then npm run test-es6; else npm run test-es5; fi;"}
If you use Travis CI for continuous integration, you could setup your .travis.yml
like this:
language: node_jsnode_js:- '0.10'- '0.11'- '0.12'- 'iojs'
This will run your tests against multiple version of node.js and the latest 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.