http://masnun.com/2015/11/11/using-es7-asyncawait-today-with-babel.html
Let’s take a code snippet that contains the demonstration of async/await — https://gist.github.com/patrickarlt/8c56a789e5f185eb9722 – our objective is to transpile this piece of code to ES5 (current day Javascript) so we can run it with today’s version of NodeJS.
You will notice a command on top of the snippet which no longer works because Babel JS has changed. I am going to describe how we can do it with the latest version of babel as of this writing (6.1.4 (babel-core 6.1.4)).
Install Babel and Plugins
The new Babel depends on individual plugins to transform and parse codes. To transform async functions, we shall use the transform-regenerator
plugin. We also need to add the syntax plugin to recognize the async/await syntax. Otherwise Babel won’t recognize those. Apart from that, we also install the ES2015 preset which includes a sane set of plugins for transforming ES6 to ES5. We will keep those so we can use other ES6 goodies.
First we install babel-cli globally:
1
|
npm
install
-
g
babel
-
cli
|
Here’s our package.json file so you can just do npm install
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
{
"name"
:
"awesome-async"
,
"version"
:
"1.0.0"
,
"description"
:
""
,
"main"
:
"github.js"
,
"scripts"
:
{
"test"
:
"echo \"Error: no test specified\" && exit 1"
}
,
"author"
:
""
,
"license"
:
"ISC"
,
"dependencies"
:
{
"babel-plugin-syntax-async-functions"
:
"^6.1.4"
,
"babel-plugin-transform-regenerator"
:
"^6.1.4"
,
"babel-polyfill"
:
"^6.1.4"
,
"babel-preset-es2015"
:
"^6.1.4"
,
"request"
:
"^2.65.0"
}
}
|
Configuring Babel
Here’s the .babelrc
file I put in the same directory:
1
2
3
4
|
{
"presets"
:
[
"es2015"
]
,
"plugins"
:
[
"syntax-async-functions"
,
"transform-regenerator"
]
}
|
The file tells babel how to transform your code.
Transpile & Run
Once we have installed the dependencies, we can then start transpiling the codes to JS:
1
2
|
babel
github
.es6
-
o
github
.js
node
github
.js
|
You might run into a problem like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/
Users
/
masnun
/
Projects
/
awesome
-
async
/
github
.
js
:
34
return
regeneratorRuntime
.
async
(
function
printPublicGists
$
(
_context
)
{
^
ReferenceError
:
regeneratorRuntime
is
not
defined
at
printPublicGists
(
/
Users
/
masnun
/
Projects
/
node
/
github
.
js
:
34
:
10
)
at
Object
.
<
anonymous
>
(
/
Users
/
masnun
/
Projects
/
node
/
github
.
js
:
63
:
1
)
at
Module
.
_compile
(
module
.
js
:
460
:
26
)
at
Object
.
Module
.
_extensions
.
.
js
(
module
.
js
:
478
:
10
)
at
Module
.
load
(
module
.
js
:
355
:
32
)
at
Function
.
Module
.
_load
(
module
.
js
:
310
:
12
)
at
Function
.
Module
.
runMain
(
module
.
js
:
501
:
10
)
at
startup
(
node
.
js
:
129
:
16
)
at
node
.
js
:
814
:
3
|
It’s because we need to include the regenerator run time. The runtime is packed in the babel-polyfill
we have already installed. We just need to include it in our source code. So the final github.es6 file would look like this:
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
40
41
42
43
|
require
(
"babel-polyfill"
)
;
import
request
from
"request"
;
// promise returning function
function
get
(
url
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
request
(
{
method
:
'GET'
,
url
:
url
,
json
:
true
,
headers
:
{
'User-Agent'
:
'request'
}
}
,
function
(
err
,
resp
,
body
)
{
if
(
err
)
{
reject
(
err
)
;
}
else
{
resolve
(
body
)
;
}
}
)
;
}
)
;
}
// create a new "async" function so we can use the "await" keyword
async
function
printPublicGists
(
)
{
// "await" resolution or rejection of the promise
// use try/catch for error handling
try
{
var
gists
=
await
get
(
'https://api.github.com/gists/public'
)
;
// now you can write this like syncronous code!
gists
.
forEach
(
function
(
gist
)
{
console
.
log
(
gist
.
description
)
;
}
)
;
}
catch
(
e
)
{
// promise was rejected and we can handle errors with try/catch!
}
}
printPublicGists
(
)
;
|
Now if we transpile and run again, it should work fine.