Node.js 下一波大浪潮

前段时间写了一篇名为《是时候该学 Swift 了》的文章,强力安利了一下 Swift。也许很多人,尤其是老程序员们,可能并不是很认同这个观点,觉得 Swift 还是无法与传统的 C、C++、Java 之类的抗衡。不过没关系,我们今天不是继续安利 Swift,我们今天是来安利 Node.js 的。

其实本文的英文,在我的想法中应该是:”The next big thing: Node.js”,然而,好像很难翻译成中文的样子,于是乎就接地气一点的,把中文名写成了《Node.js 下一波大浪潮》。

为什么要在今天这个时间点来安利呢?因为,据说今天是 Node.js v6 要准备 LTS 的日子了

按照计划来看的话,2016 年 10 月 18 日,也就是今天应该 Node.js v6 就会成为 LTS(Long-term Support) 版本了。考虑到时区的问题,官网现在并没有更新。当然,也不排除跳票的可能性,现时最新版本的 Node.js 是 v6.8.1

重新认识 Node.js

其实早年的时候,我对 Node.js 的印象并不是很好。混乱的版本发布,乱七八糟的调用,太过于灵活的语法,还有社区的分裂等。当然,我自己平常并不经常使用 JavaScript 作为主要的编程语言可能也是问题之一,毕竟不少人觉得 JavaScript 是世界上最好用的语言。而且坊间也时有传闻,不少原来用 Node.js 搭建的网站,也逐渐地使用其它语言重写了。

重新关注 Node.js 是在大概 8 月份的时候。因为做项目的原因,想要寻找一种又快速效率又高,又可以复用前端工程师的方法。于是乎在 JAS 同学的「布道」下,开始重新了解起 Node.js。

先说说版本

让我重新考虑 Node.js 的一个主要原因是版本,也许说出来很多人不信,但,这是真的。

Node 社区闹过分裂,现在好了。Node.js 跟 io.js 又重新合并到一起了。然后,把之前混乱的版本号终于统一起来了。

而且,最最重要的是,他们有了 LTS 版本了!!!这意味着什么?意味着,你再也不会出现昨天编写的代码,明后天部署到服务器发现,TMD 语法不兼容了,NPM 包不行了,版本太旧了,然后你就要花很多的时间重新梳理代码,重新处理依赖关系等。

而 JavaScript 的粉丝们,大多年轻充满热情,又非常热衷于新东西。这也导致到他们很少考虑长期商业使用的情况,但对于企业来说,程序能长期稳定的运行才是最重要的。

早期的时候因为不稳定,运维人员往往还要做很多监控手段,一旦发现服务器挂了,就要赶紧重启相关的服务,也是让人觉得很痛苦的。当然,为了服务器可以长期稳定地运行,现在还是需要做这些工作的。

ECMAScript 6

也许大部分人对于 ECMAScript 这个名字很陌生,然而它才是 JavaScript 真正的名字。JavaScript 实际上是当年 Netscape 为了借着 Java 这个热点炒作自己而起的名字,它最早在 Netscape 发布的时候叫做 LiveScript。就我个人而言,我觉得其实 LiveScript 反而还好听一点。

那为什么叫 ECMAScript 呢?因为 1996 年的时候 Netscape 把 JavaScript 递交到了 ECMA International 以便对其进行标准化。而且标准化过后的名字就是 ECMAScript 了。然而这个名字太傻了,别说普罗大众,连攻城狮们都嫌弃,所以除了在很正式的会议和标准化文档中,大家还是习惯使用 JavaScript 这个名字来指代。

ECMAScript 6 (ES6) 实际上是 2015 年已经完成了标准化的 ECMAScript 的第六个修正版,一般大家简称为 ES6。

而这个 ES6 就厉害了,引入了超级讨好的语法糖、解构、let 和 const 等新特性。简单来说,很多的语法都得到了简化,使得开发速度得以提升。最重要的是,JavaScript 引入了「类」,变成了真正意义上的面向对象语言。还有「模块」特性的引入,使代码变得更加简洁和可维护。当然,还有更多语法相关的改善,但本文的重点不是介绍 JavaScript ES6,就不展开了介绍了。

总之,ES6 很未来,很先进,很好用,很流弊,这样。

异步和 Callback Hell

Node.js 的效率高是出了名的,这个就不需要单独再拿篇幅来写了。但是这种高性能是建筑在异步处理这一实现之上的。类似于 Nginx,所有的处理都需要用到回调(Callback),否则就会造成堵塞(Blocking),甚至比用传统的 Apache 更慢。

当然,有利有弊,让人又爱又恨的 Node.js,最要命的一点就是其 Callback Hell,它会让代码的可读性大大降低。于是乎,后来大家就开始使用 Promise 来处理异步调用了。现在 ES6 可以使用生成器(Generators)来解决这个问题,再也不用担心 Callback Hell 的问题了。更好的方式是使用 Babel 在 ES6 实现 awaitasync 功能,这样可以进一步地提升开发效率和代码可读性。写代码感觉就像是编写同步代码一样,让研发人员专注在功能和逻辑的开发上,而不是操心如何处理一层又一层的回调。

举个 Callback Hell 的例子,像下面这样的代码,当你要理解逻辑的时候,就会变得异常的痛苦:

1
2
3
4
5
6
7
8
9
10
11
12
13
a(function (resultsFromA) {
b(resultsFromA, function (resultsFromB) {
c(resultsFromA, function (resultsFromC) {
d(resultsFromA, function (resultsFromD) {
e(resultsFromA, function (resultsFromE) {
f(resultsFromA, function (resultsFromF) {
console.log(resultsFromF);
})
})
})
})
})
});

实现 Node.js 的引擎

现在的 Node 基本上都是基于 Google Chrome V8 引擎实现的。可以说,如果 Google 没有开源 V8 引擎,就不可能有 Node.js 的春天。包括知名的 MongoDB 也离不开 V8 引擎的支持。

然后,随着 Microsoft 最近越来越开放,Google Chrome V8 的竞争对手也来了。那就是 Chakra,微软最新一代浏览器 Edge 的御用 JavaScript 处理引擎,据说在某些特定情况下,其处理效率远远超过 V8 引擎。而且 Chakra 源代码可以直接在 GitHub 上找到。Node.js 官方的代码仓库,也能找到基于 ChakraCore 的 Node.js

不得不说,未来这个世界,真的是越来越开放,越来越合作共赢了。这也意味着,在将来 Node.js 将获得更好的跨平台支持。随着微软的进入,也许将来 Node.js 不仅仅在服务端和浏览器端有所建树,说不定 PC 端也能用 JavaScript 来开发了。还有原来的 PhoneGap,现在也成了 Apache 基金会旗下的 Cordova,在性能不是主要需求的情况下,我们又怎么能知道 JavaScript 是否也会横扫移动端呢?

配套工具

第一个要介绍的就是 MEAN 大杂烩,这个是一个合集,包括了:

基本上就是你开发一个 Web 应用的所有方面都覆盖到了,这就跟我们 2000 年左右流行的 LAMP(Linux + Apache + MySQL + PHP) 一样。基本上就是一个开箱即用的全家桶,如果想省事的话,直接用全家桶吧。

除了全家桶,其实还有很多的框架可以选择,比如:

基本上从 Web 到 API 到轻量应用全部都覆盖到了,剩下的就是你的 Idea 和动手能力了。

而且测试也有很多不错的框架可以使用,比如:

当然,还有其他很多不错的框架,并未能一一列举,简而言之,就是整个社区来讲,现在比较成熟了,而且可以选择的框架也很丰富,用别人造好的轮子,可以快速地实现产品原型。

Next Big Thing?

没有入坑的小伙伴,可以考虑入坑了。新版的 Node.js 虽然真的很吸引人,但我个人感觉这还是一个坑。为什么说是坑呢?因为不管什么语言到了一定的程度,总是会有各种各样的坑是规避不了的。但社会总是会进步的,IT 业也是一样。你今天让工程师用 MFC 去写一个 Windows 的应用程序,我估计大部分人更情愿用 C#,毕竟两者的效率相差实在是太大了。

工具除了好玩之外,根本还是要从解决实际生产中的问题为出发点。之前我不愿意尝试 Node.js,是因为我觉得它更像是一个极客的玩具而不是一个生产力工具。今天我们也许该尝试一下,看看 Node.js 对于我们是个惊喜还是有惊无喜。说不定,Node.js 真的就是下一个 Big Thing 呢?期待……