I really want to use ES6 in my web project.
Because I want my career to stay current and well ES6 is the bees knees!
Like what?
Well there is the Let keyword for starters.
Big Chiwawa
Ok what about destructuring now that is cool.
(Post Google Search) Ok I’ll give you that is cool.
Also Default Args, Shorthand Properties, Computed Properties, Spread Operator, String Templates, Block Scoping. The list goes on and on …
And import modules?
Err not quite. You’ll still need Babel for that!
(Annoyed at the thought of researching how to set this up)
(Seeing furrowed brow) Don’t panic all the info you need is here.
Yay
I hate red marks. But I love linting.
This is highlighted as red because the current version of Javascript for the project is not set to ES6.
Head to Preferences -> Languages and Frameworks -> Javascript
And select ES6!
Yay Red is gone!
One would think but as you know JS is in a state of flux and not all features are available in all environments.
I knew this wouldn’t be easy. What works where?
Take a look at this compatibility table. It gives a great overview of ES6 support across, browsers, polyfills, servers and mobile.
Oh great can you just give me the tl;dr;
Well many commands are available natively but professional Software Engineers like good build tools and organised code. So in order to use Module Loading via ES6 import statements most developers use a transpile — Let’s try Babel.
Let’s assume we have a Math module which performs the addition task sumTwo(number1, number2)
guess what this sums two numbers.
ok that’s nice
But as part of a larger program this is located in the file lib/addition.js
It would be nice to see the whole file contents.
function sumTwo(number1, number2){return a + b;}
export { sumTwo }
Then we want to use this function in a file called main.js
'use strict';import { sumTwo } from 'lib/addition';
console.log("2 + 3 = ",sumTwo(2,3) // 5);
If you run this in Node you will see this:
Genes-MacBook-Pro-2:javascriptzzzzzzzz thinkjones$ node -vv7.0.0Genes-MacBook-Pro-2:javascriptzzzzzzzz thinkjones$ node articles/using_es6/main.js/Users/thinkjones/dev/javascriptzzzzzzzz/articles/using_es6/main.js:3import { sumTwo } from 'lib/addition';^^^^^^SyntaxError: Unexpected token importat Object.exports.runInThisContext (vm.js:76:16)at Module._compile (module.js:545:28)at Object.Module._extensions..js (module.js:582:10)at Module.load (module.js:490:32)at tryModuleLoad (module.js:449:12)at Function.Module._load (module.js:441:3)at Module.runMain (module.js:607:10)at run (bootstrap_node.js:382:7)at startup (bootstrap_node.js:137:9)at bootstrap_node.js:497:3Genes-MacBook-Pro-2:javascriptzzzzzzzz thinkjones$
As far as I am aware import
is not supported and is still under heavy discussion. That’s why there are so many polyfill and transpiler libraries. To help with this intermediate phase the JS ecosystem.
So great how can I get this to work.
Let’s try Babel seems to be popular. From front page docs “Start by installing the Babel CLI and a preset”:
npm install --save-dev babel-cli babel-preset-env
Then “Create a .babelrc file in your project (or use your package.json)”
{ "presets": ["env"]}
WTF is that?
Well it’s a mechanism to take into account the target environment you are aiming for. Since Different products and versions of products support different ES6 systems natively you can optimise this by specifying your target environment.
Sounds complicated should I give a f***?
Not sure. I think for this example we will go with the default and investigate if we find issues.
Do you work for a startup?
Yes
I love how scrappy you are.
K lets try running it again node main.js
Ahhh! SyntaxError: Unexpected token import”
See…
So Babel doesn’t actually do anything you need to compile or rather transpile the code into an ES5 format that the target environment understands.
Yeah yeah — so how do I do that?
Well I am glad you asked. Babel has an awesome setup page where you select your build tools and get the necessary info — Babel Setup Page Link
Let’s use the Babel CLI
Install CLI Locally npm install --save-dev babel-cli
Then trans-pile:
./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist
Way what’s this src directory?
Yeah when I started the article I had all my files in root, but then after playing with Babel and realised it was going to produce a bunch of output files I decided to use a different src and dest directory.
Sounds good — So what do we have now?
Here you go — two directories one with the src and another with the dist files.
Yeah all well an good but does the program now run?
Yeah it should.
Yeah are you sure?
No let’s try it in Node.
node dist/main.jsmodule.js:474throw err;^
Error: Cannot find module 'lib/addition'
DAMMMIT!
So this is down to my limited Node knowledge but it depends on how relative file references are specified. My main.js
file was located at /src/main.js
and I was running node from /
. So I think the import is relative to the node running directory when specified like this:
import { sumTwo } from 'lib/addition';
So when it was running it wasn’t working, because it was expecting the file in /lib/addition.js
and not /dist/lib/addition.js.
To fix this I had to change the original import statement to be relative to the current directory. So changing it to:
import { sumTwo } from './lib/addition';
Then re-running Babel compile by:
./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist
Gives me the correct transpiled code:
'use strict';
var _addition = require('./lib/addition');
console.log("2 + 3 = ", (0, _addition.sumTwo)(2, 3) // 5);
Which then runs when I call this command from the root directory:
node ./dist/main2 + 3 = 5
YAY!
All well and good where is the code?
Here at my github — thinkjones