浏览器之外的 JavaScript——2016 年我们期待些什么
这是三篇连载《2016 年我们对 JavaScript 期待些什么》的第三篇。整篇文章取自我们的白皮书《JavaScript 的未来:2016 及以后》。今天的贴文集中于 JavaScript 语言本身的未来。第一篇涵盖了 JavaScript 框架的未来,可以在这里找到,第二篇则涉及语言的演进,可以在这里找到。
过去几年,JavaScript,一种为 Web 浏览器设计的脚本语言,已经广泛应用于各种软件应用中。加上 JavaScript 目前运行在服务端的代码,用来驱动 iOS 和 Android 的应用,甚至用来控制机器人,已经很难找到一种不受 JavaScript 影响的软件生态系统了。
驱动 JavaScript 扩张到这些“新疆界”的部分因素是性能。然而,几年前在服务器上运行 JavaScript 还是不可想象的,谷歌 2008 年进入浏览器和 JavaScript 引擎市场点燃了性能竞争的战火,竞争的结果极大地提升了语言的运行速度。而最近像 asm.js 这样的努力进一步推进了这一工作。
本文将讨论 JavaScript 框架的下一步发展,如用于运行服务端 JavaScript 的框架, 用于构建移动应用以及桌面应用的框架等。我们将听听众多直接构建这些解决方案的开发人员的看法。我们就从或许是 JavaScript 的第一个新疆界 Node.js 开始吧。
Node.js
Node.js 是一个基于谷歌 V8 JavaScript 引擎的开源运行时环境。虽然很多公司、框架都试图在服务器上运行 JavaScript,Node.js 却是在服务端大规模运行的第一款运行时。
Node.js 写于 2009 年,此后即声名鹊起。使用 Node.js 的公司众多,最近成立的 Node.js 基金会包括了诸如 IBM、Intel、Paypal 以及微软这样的公司。Node.js 的包管理器 npm 2014 年成为软件界最大的包管理器,其包含的模块数大概是 Java 和 Ruby 两者之和的两倍。
npm 包管理器的增长,图片来自 modulecounts.com
然而,Node.js 的成功并非一帆风顺。2014 年底,一群开发者借口现在的框架不活跃,没有新的贡献者参与进来,以及缺少新的发布,创建了另一个深受欢迎的分支项目。这个新的框架,称为 io.js,迅速获得了追随者以及社区的支持,很多人担心会造成 Node.js 世界的长期分裂。幸好 Node.js 和 io.js 在 2015 年 6 月实现了合并,消除了人们的担心。
合并的成果之一是形成了 LTS,即 Node.js 发布的长期支持计划。根据这个计划,Node.js 将每年实现一个 LTS 发布,并且对该发布提供 18 个月的积极支持。
这个开发周期的目标是,既满足希望处于技术前沿的开发者的需要,又满足大公司对未来数年能够依靠的稳定的发行版的需要。但这个开发周期对 Node.js 的未来也有重大影响。在我问及 Node 基金会的 Mikeal Rogers,2016 年 Node.js 最大的变化是什么时,他这样说:
“新的开发周期将是最大的变化。每年我们会有 2 次主要发行,但只有一次发行接受长期支持(LTS)。这比过去要多很多,而且过去我们从来没有真正的 LTS,这对开发者是一个很大的变化,对企业来说,也是一个采用 Node 的新机会。”
Mikeal Rogers Node 基金会
2016 年的 Node.js
2016 年期望有更多的用户采用 Node.js 及其包管理器 npm。大型企业(微软,IBM,Intel,Progress Software等等)对 Node 持续不断的支持,再加上长期支持计划这样的企业友好的举措,会刺激 Node.js 在企业中应用的增长,以取代 .NET 和 Java 这样典型的企业解决方案。
最新发布的 npm 目标是为客户端 JavaScript 提供更好的支持,以替换对客户端 JavaScript 包管理器如 Bower 等的需求,npm 中的模块数量有望持续指数级的增长。随着开发人员开始将其客户端脚本及 jQuery 插件注册到 npm 上,npm 将只会继续增长。事实上,按照 Mikeal Rogers 说法,增长的主要原因是 npm 是一个生态系统的生态系统。
“几年以前,我对 npm 的增长率进行了量化,画了一条预测曲线。那个时候,人们认为这太疯狂了,因为,预测曲线认为,要在 1 年多点的时间内,模块数量超过 100K,增长率曲线才不会是平平的。没成想,我们只在几天之内就超过了 100K,甚至我也被吓着了。
“你深入到 npm 增长的内部,你就会看到,推动增长的力量来自于 npm 是生态系统的生态系统。npm 是为各种各样的用例构建子平台的最好地方。此生态系统的某些部分一旦平稳下来,就会被新的快速增长的生态系统替换掉。”
Mikeal Rogers,Node 基金会
作为此说法的佐证,基本上本文中的所有的 JavaScript 解决方案——包括 Cordova、React Native、NativeScript——都使用 npm 作为其包管理器。在 npm 上简单搜索一下“jQuery”、“polymer”、“meteor”、“react”,就会对目前 npm 上庞大的规模有个概念。npm 是随着 JavaScript 应用的增长而增长,而随着 npm 应用的增长,Node.js 也随之而增长。对于软件领域里第一个主流的服务端 JavaScript 框架,其未来一片光明。
现在让我们把目光转向另外一些技术,这些技术不是在服务器上运行 JavaScript,而是用 JavaScript 来驱动移动应用。
PhoneGap 和 Cordova
与 Node.js 是第一个在服务器上运行 JavaScript 的主流解决方案很像,PhoneGap 是第一个使用 JavaScript 运行原生移动应用的主流解决方案。PhoneGap 最初由 Nitobj 创立于 2009 年,其后于 2011 年被 Adobe 收购。作为收购的一部分,PhoneGap 的源代码捐给了 Apache 软件基金会,从此该项目即以 Cordova 为名。今天,Cordova 是一个免费的开源框架,很多公司都成了该项目的贡献者,而 PhoneGap 成为了由 Adobe 拥有的 Cordova 的一个发行版。
几年来,Cordova 一直在为自己那性能不佳的名声而辩护,这名声起因于业界最有名的抱怨,因为这抱怨是来自于一个 2012 年最有技术影响力的人。
“反思最近这几年,我认为我们作为一个公司所犯下的最大错误,是将太多的赌注压在了 HTML5 上,而不是原生……因为它还没成熟。”
Mark Zuckerberg,Facebook
2012 年以来,很多公司都加入进来,向性能问题开战。包括 Ionic、Onsen 以及 Kendo UI Mobile 这些性能敏感的 UI 框架,Telerik 和 PhoneGap 团队对工具的改进,由 Crosswalk 提供的新的 web 视图,还有高质量的插件,这些插件可以在 Telerik 已验证插件市场找到。
Telerik 已验证插件市场
除了上面公司提供的这些对性能的改进之外,移动操作系统厂家也提供了一些新的功能特性,如 Android 的自动更新 web 视图,iOS 新的 WKWebView API 等,极大地改进了 Cordova 的性能。考虑到这一点,我请前 Adobe PhoneGap 团队的成员 Brian LeRoux 就 Cordova 的未来发表看法。
“Cordova 已经谨慎地走向稳定。我们尽力把事情做得简单,将一些功能特性分给插件接口,尽量与 Android M 及 iOS 9 的平台升级同步。已经反反复复了好几年,但‘小模块’的思维已经开始占上风,这让我很高兴。一线的开发人员可能看不到这些,除非他们要做自己的分发而对 Cordova 进行扩展。”
Brian LeRoux
2016 年的 Cordova
和 Node.js 很像,Cordova 的稳定性会吸引一些大公司,它们中的几家正在试水移动开发。使用 HTML、CSS 以及 JavaScript 开发移动应用的 Cordova 方式将会继续吸引 web 开发者,特别是和那些涉及到 Xcode 和 Android Studio 的原生开发相比。
尽管 Cordova 的应用持续增长,但其开发方式正在受到两个方面的挑战。一个是来自谷歌。谷歌正在推渐进应用(progressive apps)的概念,这种应用表面看起来像原生应用,譬如启动画面,主屏幕定位,以及离线访问,其实是真正的 web 应用。渐进应用仍然处于早期阶段,而且其功能特点只局限于 Android 版本的 Chrome。期待谷歌在 2016 年将渐进应用的概念继续向前推进。
目前对 Cordova 最大的挑战来自 JavaScript 领域的最新进展:使用 JavaScript 构建真正的原生移动应用。
原生移动应用
2015 年出现了一种新的基于 JavaScript 的移动应用开发方式,叫做“JavaScript Native”。和基于 Cordova/PhoneGap 的应用不一样,JavaScript Native 应用使用平台的原生控件及范式来构建用户界面,不用浏览器,也不用 web 视图控件。
JavaScript Native 框架试图为构建 iOS 和 Android 应用提供一种两全其美的解决方案:使用 JavaScript 来写应用逻辑(不再用 Java、Swift 等等),而用平台的原生用户界面 API 来构建应用,这样可以适配于原生操作系统,并且还能提供尽可能好的性能。
使用 JavaScript 构建的移动应用。点击此处查看源代码。
React Native 和 NativeScript 是 2015 年首批公开发布的 JavaScript Native 框架,后续又有 Fuse 和 tabris.js。不同的框架有不同的特点。例如,React Native 允许你重用 React 的 JavaScript 框架,而 NativeScript 允许你直接从 JavaScript 中访问 iOS 和 Android 的 API。但这些框架用 JavaScript 构建真正的原生应用的高阶途径是相同的。
对于 web 开发者来说,使用 JavaScript 构建原生应用的想法听起来很美妙,但与 Cordova 这样的框架比起来,这些 JavaScript Native 框架还是有些问题的。下面列出一些:
由于 JavaScript Native 框架不用浏览器,所以你不得不学一些与框架有关的 API 来搭建用户界面,而不像在 Cordova 中那样直接用 HTML。
因为 JavaScript Native 应用是原生应用,所以在构建大型应用时内存管理会成为一个问题,就像在原生的 iOS 与 Android 应用中一样。
最后,JavaScript Native 框架比较新,从而示例和教程也就比较少。相比那些已经活跃开发好多年的框架,这些框架本身也还不成熟。
关于这些框架在 2016 年会有什么发展,我分别问了 React Native 团队的 Christopher Chedeau(即 Vjeux)和 NativeScript 的产品经理 Valip Stoychev,他们的回答都集中在稳定性上。
“对于 React Native,我们结束了畅想/原型阶段,现在进入了固化阶段。你可以看到大量工作在各方面展开:性能工具/优化,改进所有核心 API,更好的错误信息,修复边界情形……。这样,Facebook 内外的工程师就可以用来构建高质量的移动应用了。”
Christopher Chedeau(Vjeux),Facebook
“随着我们的用户基数快速增长,我们要确保用户有一个稳定健壮的框架来构建真正的应用程序。所以我们会持续在性能及调试工具上进行工作,以改进 NativeScript 开发者的使用体验。另外一个主要工作是与 Angular 2 团队合作,预计会持续整个 2016 年。”
Valio Stoychev,Telerik
2016 年的 JavaScript Native
2016 年,期待 JavaScript Native 的平台能够稳定下来,能有应用在这些平台上开发。随着 React Native 和 NativeScript 框架的功能集的固化,希望看到更多的围绕这些框架创建的工具,譬如 Telerik 自己的用来创建 NativeScript 应用的 Telerik 平台。
2015 年大肆宣传的 JavaScript Native 应用能否在 2016 年大规模推广开来,只有靠时间来说明了。不过,正在用这些框架构建的高质量应用程序(参见 React Native 的案例展示和 NativeScript 的案例展示)的数量预示着,使用 JavaScript Native 方式构建应用程序,其大规模推广应用尚需时日。
对于需要带有原生界面的原生应用的公司来说,和构建 iOS 应用(用 Xcode 与 Objective-C/Swift)以及构建 Android 应用(用 Android Studio 与 Java)比较起来,特别是考虑到很多公司的开发人员都掌握 JavaScript 开发技术这一点,则 JavaScript Native 框架是一个有竞争力的选择。
总之,对于 JavaScript 开发人员,JavaScript Native 应用代表了一个令人兴奋的新疆界。JavaScript 开发人员不用为了写一个移动应用而再去学原生程序设计语言。而且移动应用也不是 JavaScript 开发人员唯一涉足的软件领域——JavaScript 开发人员也将涉足传统的桌面应用。
桌面应用
传统上,如果想构建一款 Windows 或 Mac 应用,你得用平台专用的工具,譬如 WPF 以及 Windows Forms,或像 Java、Adobe Air 这样的跨平台接口。不过,就像本文所讨论的其他软件生态系统一样,基于 JavaScript 的解决方案正在慢慢进入这片领地。
这个地盘上第一个基于 JavaScript 的解决方案是 Intel 创建的 Node-WebKit,该项目于 2011 年底开源,现在称为 NW.js,因为其内部实现从 WebKit 转到了 Chromium,工作机制类似于 Cordova,但用于开发桌面应用。
NW.js 由 Intel 开发,2011 年发布
NW.js 将一个 web 应用程序包装在一个原生的外壳中,这样就可以访问原生的桌面 API,如文件选择器、窗口菜单等等。这种组合让你能够用基于标准的 web 技术来写 Windows、OS X 以及 Linux 的桌面应用程序。时光快速向前推进几年,NW.js 就不是使用这种架构的唯一框架了。2015 年 4 月,GitHub 宣布了 Electron,这是一个类似的构建跨平台桌面应用的框架。
GitHub 的 Electron 于 2015 年 4 月发布
Electron 是作为 Atom 的外壳而开发的(Atom 是 GitHub 的一款基于 web 的文本编辑器),现在已经与 Atom 分离开来,从而任何项目都可以使用。有 GitHub 做后盾,Electron 取得了爆发性增长,目前在 GitHun 上已经超过了 20000 颗星(很快就要赶上 NW.js 的 25000颗星了)。
Electron 也在 2015 年上了头条,因为微软新的跨平台 Visual Studio Code IDE 背后的引擎用的就是 Electron。快速浏览一下社区创建的 Electron 资源,你就会知道,Electron 在开发社区是多么地受欢迎。
2016 年的桌面应用
就像本文讨论的很多技术一样,对于构建桌面应用的基于 JavaScript 的跨平台工具,前景看起来一片光明。跟随像 GitHub、微软甚至 Slack这样的公司——不仅在 NW.js 和 Electron 基础上构建,而且还用 web 技术来构建原生应用——其他公司采用 web 技术来构建桌面应用会更有底气。受 NW.js、Electron 以及其他项目的推动,期待 2016 年能启动更多的新桌面应用。
2016 年 JavaScript 的新疆界
虽然这篇文章讨论的似乎是各不相干的话题——服务端代码,移动应用,桌面应用——讲的却是相同的事情:几年之内,在这些环境之中运行 JavaScript 将从不可思议变成主流。十年之内,JavaScript 已经从一个处理图像翻转效果的玩具语言,变而成为世界上最流行的程序设计语言。而且 JavaScript 的走向,似乎还没个尽头。
2007 年,Jeff Atwood 提出了著名的“能够用 JavaScript 写的任何应用,最终都将用 JavaScript 来写”,这份宣言似乎已经成了预言。JavaScript 已经到达了本文无法涵盖的地方,譬如通过 Johnny-Five 项目而运行在硬件上,以及作为第一类对象,用来构建运行在 tvOS 上的原生应用,这是 Apple 刚刚宣布的用于 Apple TV 的操作系统。
驱动 JavaScript 增长的原因之一,是为多范式软件开发构建单一开发模式的需要。企业,尤其是小企业,通常雇不起那么多开发人员,对所有人们今天使用的如此泛滥的操作系统和设备都具备专家级的知识。甚至对于 facebook 这样规模的企业,这也成为了一个问题。正如 Chritopher Chedeau 跟我们分享的:
“对我来说,今天开发界的悲剧在于,社区被语言所分割,我们甚至将其称之为一个个的生态系统。JavaScript、Java、Objective-C、Python、C++,等等。这里面有大量的浪费,因为每个生态系统都有相同的工具,诸如包管理器,IDE,核心库,知识库……
看一个具体例子。在 Facebook,每一个具体的功能特性都要实现 3 遍:用于 Web 的, iOS 的,以及 Android 的。更糟的是,要求一个工程师在这三个生态系统中都游刃有余是不现实的,所以我们通常都是用 3 个人来实现某个具体的功能特性。这很悲哀。
“为了解决这个问题,我的直觉是,我们需要一个单一的语言/生态系统。对于 React Native,我们选择了 JavaScript,但从大局来看,具体什么语言并不重要。重要的是,平台是唯一的。”
Christopher Chedeau, Facebook
JavaScript 快速成长,对于所有这些界别(移动,桌面,服务器,硬件)来说,正在成为一种切实可行的选择,其地位的唯一性正在使得人们的渴望成为现实,即只需构建一次。JavaScript 的快速增长,在 2016 年及以后是否能够持续,只有时间才能告诉我们。但跨越软件生态系统的 JavaScript 工具的风生水起,似乎预示着还遥无尽头。
记着这点,我要引用 Brendan Eich 的名言来结束本文:“永远要把赌注压在 JS 上。”