服务器端 JavaScript:卷土重来 (上)

原文链接;作者:Michael Mahemoff

十一月的欧洲,JavaScript 会议不断。除了在德国柏林召开的 JSCONF 欧洲站和在英国布莱顿的 Full Frontal 大会,还有一场与 JavaScript 密切相关 Fronteer 会议。如果要找出三场会议的共同话题,那会是 JavaScript 跳出浏览器服务于其他领域。这个话题接着引发了更多的讨论。

对于浏览器以外的应用,服务器端 JavaScript 是最吸引人的选择,本文就此罗列了几个理由。虽然几年前这么说会令人发笑,但这正在成为现实。

浏览器之外的 JavaScript?有的应用使用的是类似浏览器的图形用户界面,例如 Adobe Air、电视机;而有些应用甚至没有图形界面,比如,有人建议将它作为一种通用的 Unix 脚本语言。

本文作者是迈克尔·麦赫马夫(Michael Mahemoff),他是 Osmosoft 的首席网页开发师,常为 Ajaxian 网站攒写文章。他的个人博客和 Twitter。

本文分两部分发出,这是上篇。

完美风暴

服务器端 JavaScript 不是新生事物。1996年,在发布了首个版本的浏览器两年之后,网景(NetScape)推出了服务器端 JavaScript ,但它的影响力远不及客户端 JavaScript,于是这个概念很快隐退,JavaScript 便主要应用在浏览器上。即便如此, JavaScript 也没有获得多少尊重,并常被贬低为一门只能用来制作恼人的警告窗口和没用的走马灯动画的语言。

但突然间,重度级网页应用开始萌发。GMail、谷歌地图和 JotSpot(可以算是谷歌文档的前身)都是在浏览器中运行。这些应用不是由 Flash 或 Active X 驱动,而是通过 JavaScript 操控浏览器的文件对象模型(Document Object Model,DOM)。这些应用被称作「Ajax」,围绕它的社团开始蓬勃发展。几年过去了,有些人认为 JavaScript 已经成为了世界上最受欢迎的编程语言。其实也不惊奇,所有的主流浏览器都将它作为标准语言。它是网页的通用语言,虽然网页开发师有各自喜好和首选的动态语言,但回到浏览器端,大家不约而同的选择了 JavaScript。今日,JavaScript 可以和英语做比:如果只计算基本掌握的人数,英语应是最受欢迎的语言。

既然能在浏览器中使用,为什么不能在服务器里呢?单种语言贯穿全线减少了既要编写服务器端脚本又要编写客户端脚本的工程师的烦恼。对项目经理来说,两端都采用通用语言能让他更轻易的在前端和后端之间调配工程师。现在有许多开发者社团已经承认了 JavaScript。事实上人们误判了 JavaScript 的缺陷,真正的问题是浏览器的文件对象模型 API ,而不是这个语言本身。如果不被这些观念所困扰,JavaScript 会是解决各式问题的得力助手。

对于这种「双端 JavaScript」的构想,这里有一个复用的故事。用不同的语言攒写同一种逻辑现在已是常事,拿校验(Validation)的过程来说,用 JavaScript 编写一段校验程序,直接在浏览器中反馈用户结果,或者用 PHP 来确保数据在提交到数据库之前的完好。但如果将服务器端程序改用 JavaScript,只需在两端部署单一的验证程序就可以了。在某些开发模式下,也可以使用浏览器中的函数直接调用服务器中的某个函数。因此代码量更少,也更容易编写,减少了处理数据传输方面的时间开支。

感谢浏览器之间的竞争,JavaScript 的性能增长也十分迅速。Firefox 的 Spidermonkey JavaScript 引擎,速度增长了 20 至 40 倍,Safari 的 Squirrelfish(又名 Nitro)的成绩也很惊人,而谷歌 Chrome 去年携高度优化的 V8 引擎登场,这款引擎可以算是高性能 JavaScript 引擎的佼佼者。

javascript_speed.png
服务器端 JavaScript 也可以同 NOSQL 数据库进行良好契合,这些数据库倾向于使用 HTTP 进行通讯,在某些情况下采用 JSON(JavaScript Object Notation)作为消息格式。JavaScript 库已经包括对此类交互形式的支持,而且程序员也驾轻就熟。一些 NOSQL 系统超越了数据存续的层面,进入了成熟的 JavaScript 应用环境。

迈向成熟的服务器端生态

运行服务器端 JavaScript 最简单的办法是将 JavaScript 引擎植入网页服务器中。有许多开源项目可选,由于不同项目所采用的编程语言不同,因此影响到它可以运行的环境,以及常见的性能和支持方面的问题。例如,许多 JavaScript 平台运行在 Rhino 引擎上,而 Rhino 构建于 Java,这意味着它们更容易同 Java 部件集成。因而,你可以在 JavaScript 中构建完整的用户见面界面 — 包括在服务器之上的瘦用户界面层 — 而且仍然可以由常见的企业级 Java 栈做支撑。Helma 即是这种架构的一例。

一旦装上 JavaScript 引擎,就可以像使用其他语言一样攒写简单的 CGI 脚本 — 读取请求、回写响应。在实践中,还需要良好的库支持。某些环境默认带库,你也可以利用为浏览器端 JavaScript 而开发的库。什么东西会带来真正的影响?是全行业的标准化。为此,活跃的草根运动正在汇集到一个完整的 API 之上:CommonJS,这个 API 界定了文件访问、网络、单元测试等,以及这些部件如何打包的方式。人们致力将这个新生的规范部署到主要的 JavaScript 引擎上(Rhino、Spidermonkey、V8、EjScript)。遵守 CommonJS 的开源平台有 Narwhal。它的势头正劲,运行在多个 JavaScript 引擎上。

CommonJS 提升了服务器端 JavaScript 的抽象层级,允许开发者使用其他环境中高级服务器的常见模板。编写 Web 服务器不再意味着手工编写低级冗余代码。因此,你得到了像 Jack 那样的框架,它类似 Python 的 WSGI 和 Ruby 的 Rack。Jack 构建于高密度「中间件」库的思想之上,能够被编写和复用。有一个叫做 Nitro 的项目,则用来为 Jack 编写组件。因此,Nitro 构建在 Jack 上,Jack 构建在 CommonJS 上。这就是服务器端 JavaScript 生态的一个例子。