Node.js Web开发_第二章(3)

电子书推荐

Become a ninja with Angular

Web Development with Node and Express, 2nd Edition

Building Server-side and Microservices with Go: Building Modern Backends and Microservices Using Go, Docker and Kubernetes

AI for Sports

Basic Linux Terminal Tips and Tricks: Learn to Work Quickly on the Command Line

Artificial Intelligence in Finance: A Python-Based Guide

Create Simple GUI Applications, with Python & Qt5

Distributed Tracing in Practice: Instrumenting, Analyzing, and Debugging Microservices
[
C Programming: Learn to Code](http://www.iebukes.com/c-prog...)

Effective Python: 90 Specific Ways to Write Better Python, 2nd Edition
[]()
[]()

使用Babel来使用实验性的JavaScript特性

Babel transpiler(转换器)是使用JavaScript最新功能或尝试新的JavaScript功能的领先工具。因为您可能 从未见过transpiler这个词,所以它的意思是将源代码从一种语言重写为另一种语言。它就像一个编译 器,Babel将计算机源代码转换成另一种形式,但Babel生成的不是直接可执行的机器码,而 是JavaScript。也就是说,它将JavaScript代码转换为JavaScript代码,在您意识到Babel的输出可以针对较 旧的JavaScript版本之前,JavaScript代码似乎没有什么用处。
更简单地说,可以将Babel配置将使用ES2015、ES2016、ES2017(等等)功能的代码重写为符合ES5版本 要求的JavaScript代码。由于ES5 JavaScript与旧计算机上的所有web浏览器都兼容,开发人员可以用现 代JavaScript编写前端代码,然后使用Babel将其转换为在旧浏览器上执行ES5 JavaScript代码。
要了解有关Babel的更多信息,请访问https://babeljs.io/
Node Green网站明确表示,Node.js几乎支持所有ES2015、2016和2017的功能。因此,实际上,我们不 再需要在Node.js项目中使用Babel。您可能需要支持较旧的Node.js版本,您可以使用Babel来实现这一 点。
对于web浏览器,需要很长时间来支持ECMAScript的最新帅能。这并不是说网络浏览器制造商在采用新 功能方面进展缓慢,因为谷歌、Mozilla和微软团队都积极主动地采用了最新的功能。不幸的是,苹果 的Safari团队在采用新功能方面似乎进展缓慢。然而,更慢的是用户更新浏览器的速度。
因此,现代JavaScript程序员需要熟悉Babel。
我们还没有准备好展示这些特性的示例代码,但是我们可以进一步了解Babel工具的设置。有关安装文档的更多
信息,请访问http://babeljs.io/docs/setup/ 然后单击CLI按钮。
为了简单介绍Babel,我们将使用它来转换我们之前看到的在Node.js 6.x上运行的脚本。在这些脚本中, 我们使用了异步函数,这是Node.js 6.x不支持的特性。
在在命令框中打开ls.js和ls2.js的目录,输λ以下命令:

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

这几个命令将安装Babel软件以及几个转换插件。Babel有一个插件系统,您可以启用项目所需的转换 器。本例中我们的主要目标是将前面显示的异步函数转换为生成器函数。生成器是ES2015引入的新函 数,为实现异步函数奠定了基础。
由于Node.js 6.x既没有fs.promises函数也没有util.promisify函数,因此我们需要进行一些替换以创建一个 名为ls2-old-school.js的文件:

const fs = require('fs');
const fs_readdir = dir => {
 return new Promise((resolve, reject) => { 
 fs.readdir(dir, (err, fileList) => {
 if (err) reject(err);
 else resolve(fileList);
 });
 });
};
async function listFiles() {
 try {
 let dir = '.';
 if (process.argv[2]) dir = process.argv[2]; 
 const files = await fs_readdir(dir);
 for (let fn of files) {
 console.log(fn);
 }
 } catch(err) { console.error(err); }
}
listFiles();

我们有前面看到的相同示例,但有一些更改。fs_readdir函数创建一个Promise对象,然后调 用fs.readdir,确保根据得到的结果拒绝或解析Promise。这或多或少就是util.promisify函数的作用。
因为fs_readdir返回一个承诺,wait关键字可以做正确的事情,并等待请求成功或失败。此代码应该
在Node.js版本上按原样运行,该版本支持异步函数。但我们感兴趣的是,我们之所以添加fs_readdir函 数,是因为它在较旧的Node.js版本上的工作方式。
fs_readdir中使用的模式是在异步函数上下文中使用面向回调函数所需的模式。
接下来,创建一个名为.babelrc的文件,其中包含以下内容:

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

该文件指示Babel使用我们先前安装的命名转换插件。顾名思义,它将异步函数转换为生成器函数。 由于我们安装了babel cli,因此安装了一个babel命令,以便我们可以输入以下内容:

$ ./node_modules/.bin/babel -help

要转换代码,请运行以下命令:

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

此命令传输命名文件,生成一个新文件ls2-babel.js。新文件如下:

'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 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); 
});

这段代码对人类来说并不容易阅读。相反,这意味着编辑原始源文件,然后将其转换为目标JavaScript引 擎。需要注意的主要事项是,传输的代码使用生成器函数(表示函数*表示生成器函数)代替异步函数, 并使用yield关键字代替wait关键字。生成器函数是什么以及yield关键字的确切作用并不重要;唯一需要 注意的是,yield大致相当于wait,_asyncToGenerator函数实现了类似于异步函数的功能。否则,传输的
代码相当干净,看起来与原始代码非常相似。
传输的脚本按如下方式运行:

$ nvm use 4
Now using node v4.9.1 (npm v2.15.11)$ node --version v4.9.1
$ node ls2-babel
.babelrc
app.js
ls.js
ls2-babel.js
ls2-old-school.js
ls2.js
node_modules

换句话说,它与异步版本运行相同,但在较旧的Node.js版本上运行。使用类似的过程,您可以转换使用 现代ES2015(等等)结构编写的代码,以便它可以在旧的web浏览器中运行。
在本节中,我们学习了JavaScript语言的进步,特别是异步函数,然后学习了如何在较旧的Node.js版本或 较旧的web浏览器中通过Babel来使用这些功能。

总结

在本章中,您学到了很多关于使用Node.js的命令行工具安装Node.js和运行Node.js服务器的知识。我们还轻松地讨论了很多细节,本书稍后将介绍这些细节,所以请耐心等待。
具体地说,我们介绍了下载和编译Node.js源代码、安装Node.js以在主目录中进行开发或在系统目录中进 行部署,以及安装npm(Node.js使用的事实上的标准包管理器)。我们还了解了如何运行Node.js脚本 或Node.js服务器。然后,我们查看了ES2015、2016和2017中的新功能。最后,我们看了如何使 用Babel在代码中实现这些特性。
现在我们已经了解了如何设置开发环境,我们准备开始使用Node.js实现应用程序。第一步是学 习Node.js应用程序和模块的基本构建块,这意味着要更仔细地了解Node.js模块,如何使用它们,以及如 何使用npm来管理应用程序依赖关系。我们将在下一章中介绍所有这些。

你可能感兴趣的