Backbone.js 解决前端复杂之道

在上期的FCity网站前端优化指南出来后,都在一直在想对应的解决方案,本写先动手完成ASP.NET MVC下的JavaScript依赖管理、压缩和合并的小工具,但在近半个月的对前端体系了解中学到了更多的东西,如果把最新的优秀实践融合,也是一个难题。

这其中有一个很好的js库,Backbone.js!其提供了Models, Collections, Router,Views。Models 用来创建数据,校验数据,绑定事件,存储数据到服务器端;Router中定义了路由及对应的Controller;Views 用来展示数据。这样前端也做到了数据和显示分离。

谈谈FCity的Site

FCity的网站很特别,它是由Flash转为HTML,并为了支持iPad做了两个版本,其中一个则要考虑大多数的浏览器,像打不死的IE6,iPad上则简单许多,更多的HTML 5新特性都可以使用。

这样就有一个问题,开发人员仍使用了Flash的观点,全站只有一个Page,属于典型的Single Page Application ,大量的内容一次性加载,但作为互联网企业型网站,使用者看来也算不上大问题。这个系统有点像葫芦,两头粗,中间细。数据库逻辑复杂,前端也承载大量的运算,但中间层则相对简单。这样对前端的架构要求自然就高了,但可惜的是,前端从未被重视,这个系统的创建者似乎也不大关注这方面,他们只是在命名空间上对公共变量进行了统一定义,抽像出了共用的函数,但这个系统无疑要求更多。

全站使用jQuery唯一的库,但jQuery本身作为一款很棒的DOM操作工具,其关不提供架构层面上的支持,相反,在某些时候它还诱导初级工程师写出性能很低的代码。这一些YUI3做的就相当的棒,但却因其不善推广,加之其学习成本偏高,导致其市场占有率不高。

一个js文件长达2000行,且没有注释,逻辑、数据和视图则完全耦合在一起,每次修bug时都由衷的佩服那些写这些代码的人,他们一定是有着超强的记忆力。不是专业的前端,有次我为了修一个2的bug,却引发2个1的bug,这样的示例不算少数。

####期望是什么

  • 所有 state 和 model 放在同一个地方
  • Model 数据变动自动同步到 UI
  • 清晰便于维护的代码结构
  • 尽可能少的 “耦合代码”
  • 可被测试

####前端复杂化?

朋友问我,前端本来是件很简单的事情,为什么要用一堆的理论和模式去复杂化?包括ECMAScript 5,都让JavaScript正在失去其简单的特性。

其实这个答案也很简单,那就是前端正在承担越来越多的工作,JavaScript作为Browser里唯一被执行的语言,互联网发展要求其不断的更新。像FCity这样的用HTML+JS架构的网站并不少,简单的东西累加在一起,当超过一个阈值时其复杂度就会出现爆炸性上升。

####架构理论

这种所谓的架构的支持是指什么?在Zakas的这篇Nicholas Zakas — Scalable JavaScript Application Architecture都有列出,但却没有提到Web上的MVC,这种优秀的模式被实践证明了无数次,但在前端却仍是一门新奇的东西,有关他的实践也很多,但由于早期的Web都很简单,加之JavaScript语言的不足,这方面的应用一直都不火,直到twitter, douban等一大批的互联网实践者让重心放在页面上,用实践证明这些理论的可行性,同时一系列的开源工具将这一过程简化。backbone.js就是这么一个优秀的工具。

####Backbone.js是什么

Backbone supplies structure to JavaScript-heavy applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.

说白了就是一个js写的浏览器端的MVC库。周未花了两天时间调试了下它的源码,并试着写了两个小的demo,虽然对于如何进行大型应用仍不大熟悉,但足可见其威力。目前在用它的网站有:LinkedIn Mobile, Flow, GroupOn, Basecamp Mobile, Douban Shuo。

首先Backbone.js提供了Model,支持conversions,验证、计算和存储;则Collection则是一个有序的Model集;在新版中Controller被Router替换,在routers中指定controller方法;history则提供router的信息,Model和Collections中都有对应的事件机制,当数据发生发变时会执行相应的行为(重新绑定页面);当model中的数据被提交时,触发sync事件;View负责显示层的展现,但backbone并不提供模版引擎,普遍使用的是Mustache, haml-js,(View中也有针对dom的方法,当DOM事件被触发时,响应相应事件);Event机制保持视图和数据的一致;更祥细的教程参见官网和TODOs的示例。

####假如Backbone用在FCity中

在这个大型的Web应用中,可以试想,如果使用类似的MVC模式,前端代码的职责会更加清晰,业务和视图不再有耦合,对领域的定义也格外明了,

更大的好处就是对不同平台支持,像iPad和浏览器之间的差异,就可以直接绑定不同的模版,当需求发变时,不会过多产生破坏性。

####未提到的话题

模块化和按需加载

####问题

这个实现的可能性太小了,公司不会为了更好的架构去花很大的精力去,除非真的项目已经到了无法维护的尽头。但这种互联网架构的趋势却已存在。

#####引用

官网
Building a single page app with Backbone.js, underscore.js and jQuery
用 Backbone.js, underscore.js 和 jQuery 创建页面应用
Hello Backbone.js (Backbone Tutorial Code)
Backbone Tutorials
《Backbone.js API中文文档》节选——Backbone.Events
Traces, 一个基于Rails 3.1的Backbone.js & CoffeeScript 应用实例
Spine,另一套MVC类库
knockoutjs,和Backbone.js到处对比的另一套MVVM库
从豆瓣说和Backbone.js说开去 (内容基于旧的版本)
让我们用Backbone.js来写一个HelloWorld程序

#####使用站点:

Multi-Level Backbone Gallery
豆瓣说
great hackernews discussion /w post from author
A Backbone.js demo app (Sinatra Backend)