官术网_书友最值得收藏!

Using Babel to use experimental JavaScript features

The Babel transpiler (http://babeljs.io/) is a great way to use cutting-edge JavaScript features on older implementations. The word transpile means Babel rewrites JavaScript code into other JavaScript code, specifically to rewrite ES-2015 or ES-2016 features to older JavaScript code. Babel converts JavaScript source to an abstract syntax tree, then manipulates that tree to rewrite the code using older JavaScript features, and then writes that tree to a JavaScript source code file.

Put another way, Babel rewrites JavaScript code into JavaScript code, applying desired transformations such as converting ES2015/2016 features into ES5 code that can run in a web browser.

Many use Babel to experiment with new JavaScript feature proposals working their way through the TC-39 committee. Others use Babel to use new JavaScript features in projects on JavaScript engines that do not support those features.

The Node Green website makes it clear that Node.js supports pretty much all of the ES2015/2016/2017 features. Therefore, as a practical matter, we no longer need to use Babel for Node.js projects. 

For web browsers, there is a much longer time lag between a set of ECMAScript features and when we can reliably use those features in browser-side code. It's not that the web browser makers are slow in adopting new features, because the Google, Mozilla, and Microsoft teams are proactive about adopting the latest features. Apple's Safari team seems slow to adopt new features, unfortunately. What's slower, however, is the penetration of new browsers into the fleet of computers in the field. 

Therefore, modern JavaScript programmers need to familiarize themselves with Babel.

We're not ready to show example code for these features, but we can go ahead and document the setup of the Babel tool. For further information on setup documentation, visit http://babeljs.io/docs/setup/, and then click on the CLI button.

To get a brief introduction to Babel, we'll use it to transpile the scripts we saw earlier to run on Node.js 6.x. In those scripts we used async functions, which are not supported in Node.js 6.x. 

In the directory containing ls.js and ls2.js, type these commands:

$ npm install babel-cli \
       babel-plugin-transform-es2015-modules-commonjs \
babel-plugin-transform-async-to-generator

This installs the Babel software, along with a couple of transformation plugins. Babel has a plugin system so that you enable the transformations required by your project. Our primary goal in this example is converting the async functions shown earlier into Generator functions. Generators are a new sort of function introduced with ES2015, which form the foundation for implementation of async functions.

Because Node.js 6.x does not have util.promisify, we need to make one substitution:

// const fs_readdir = util.promisify(fs.readdir);
const fs_readdir = dir => {
return new Promise((resolve, reject) => {
fs.readdir(dir, (err, fileList) => {
if (err) reject(err);
else resolve(fileList);
});
});
};

This structure is more or less what the util.promisify function does.

Next, create a file named .babelrc containing the following:

{
"plugins": [
"transform-es2015-modules-commonjs",
"transform-async-to-generator"
]
}

This file instructs Babel to use the named transformation plugins that we installed earlier.

Because we installed babel-cli, a babel command is installed such that we can type the following:

$ ./node_modules/.bin/babel -help  

To transpile your code, run the following command:

$ ./node_modules/.bin/babel ls2.js -o ls2-babel.js  

This command transpiles the named file, producing a new file. The new file is as follows:

'use strict';

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

const fs = require('fs');
const util = require('util');
// const fs_readdir = util.promisify(fs.readdir);

const fs_readdir = dir => {
return new Promise((resolve, reject) => {
fs.readdir(dir, (err, fileList) => {
if (err) reject(err);
else resolve(fileList);
});
});
};

_asyncToGenerator(function* () {
var dir = '.';
if (process.argv[2]) dir = process.argv[2];
const files = yield fs_readdir(dir);
for (let fn of files) {
console.log(fn);
}
})().catch(err => {
console.error(err);
});

This code isn't meant to be easy to read by humans. Instead, it's meant that you edit the original source file, and then convert it for your target JavaScript engine. The main thing to notice is that the transpiled code uses a Generator function in place of the async function, and the yield keyword in place of the await keyword. The _asyncToGenerator function implements functionality similar to async functions.

The transpiled script is run as follows:

$ node ls2-babel
.babelrc
app.js
babel
ls.js
ls2-babel.js
ls2.js
node_modules

In other words, it runs the same as the async version, but on an older Node.js release.

主站蜘蛛池模板: 社会| 应用必备| 获嘉县| 沅陵县| 隆子县| 常熟市| 宜宾县| 湟中县| 太谷县| 丰城市| 句容市| 屏南县| 遂昌县| 衡东县| 宁强县| 翼城县| 垦利县| 雅江县| 荔浦县| 肥城市| 石城县| 绥芬河市| 嘉兴市| 富裕县| 新闻| 四川省| 民县| 黑河市| 瓦房店市| 邢台县| 大新县| 年辖:市辖区| 肃南| 彭阳县| 萝北县| 定结县| 三河市| 邹平县| 长沙市| 桦甸市| 浦北县|