#BackboneConf2012 MVC Module Magic (through require.js) by Alex Sexton

Backbone Conf 2012

有幸去美国波士顿参加了2012年的 Backbone.js Conference,见到了coffeescriptunderscore.js 还有 backbone.js 的作者 Jeremy Ashkenas。会议内容围绕前端MVWTF和社区进行了很多有趣的讨论,有很多有价值的观点。我希望在这里面与大家分享我从里面学到的东西。

这系列博客其实是我整理的会议笔记的汇总,是我对每个话题中比较有印象或者比较重要的内容的摘抄,这些观点几乎都不是我的,我仅作为一个传声者。我是希望把所有的Credit交给演讲者自己,我最多只是一个翻译者,碰巧幸运的在现场。Backbone.js Conference和O’Reilly的Fluent Conference 碰巧同时进行,#BackboneConf 更加草根,但是也更有观点。

MVC Module Magic (through require.js) by Alex Sexton

Alex Sexton

副标题APP structurizer, build easifier, and middleware magician

Links

Notes

Sexton这个姓很有趣吧?他在Slides里面提到了MVWTF这个叫法,满场大笑。这个说法就是Controller还是Router还是Whatever都没关系,大家都统一MV应该是大部分逻辑的所在就对了。

Module是很多语言内置的特性,实际上就是一个返回对象的函数。难点是如何设计一个nice和neat的api。Module可以帮助你整理/分解你的系统。因为大家认为把相关的内容放在一起可以帮助你的大脑在更小的上下文中工作,让你的大脑工作的更高效(但是上下文也可以理解为一个视图,也许有其它更好的方法解决它,如Kickstarter上面Chris Granger正在实现的Light Table。不过分开的文件起码在目前的Cmd+T支持下非常好用)。有个曾经流行过的词形容Module,那就是“关注点分离”。

由于MVWTF是关注点分离,Module系统可以说是为了代码复用和关注点分离而存在,所以两者简直就是天生的一对。

Alex举的例子是如何组织一个项目的Module结构,能否每个model或者每个view是一个单独的js文件?这样的好处是报错的时候可以直接跟踪到某个文件的某一行,而不会对package过的assets的行号搞晕。Module里面声明依赖的好处是可以按需下载,如果没有需要的时候不会去解析额外的内容。当然,你还可以给module加alias,这样就可以简单的替换掉一个库的依赖(如lodash替代underscore)。

template也是一种依赖,把他们作为dom元素夹带document里面不能cache。作为类似Module的依赖可以带来性能提升。所以有了text!的前缀(不会被eval,只作为string返回)。style也是一种依赖,它可以作为template的依赖,还有其它以文本形式存在的依赖。

Alex原话

“I prefer AMD and I specifically use RequireJS. I think it’s the best solution for modules on the web that we currently have.”

AMD嘛……Async,The web is ASYNC

AMD包会改变一个Module的声明语法,所以如果不愿意直接修改你的源文件,那么完全可以加入一个编译任务来生成AMD兼容的文件。当然,这只是可以……后面有更好的方法

当然,社区里面关于AMD有很多的FUD(绝对比分号之争要鲜明,很多人明确表示AMD的语法太二而不愿意改变),Alex尽力解释了其实它的语法挺简洁的(比Node.js的require)。

然后Alex介绍了重头的Use.js,它是一个帮助使用AMD的语法引用不兼容AMD的Module的工具。这样就不需要强制人家把自己的库修改为AMD兼容的方式(对于非AMD环境不可用),或者fork一个AMD版本的库一直跟着原来库的发布(这是非常非常二的做法,后患无穷!)。其实这个工具就是动态的注入了AMD需要的前面和后面的那一丁点wrapper js code。

Plugins是在return object之前动态修改的一个机制。

Plugins是一种很好的思路:可以动态修改不支持AMD的代码,可以动态增加依赖(如template依赖于handlebar,自动插入这个依赖),自动预先编译template(这个需要 build process帮助),注入检查点或者编译期优化什么的,可以自动分析template依赖的css,可以自动inline css和images,可以动态删除用不到的代码(根据某些runtime变量的状态决定,has.js)。最终的目的甚至包括直接把整个应用的依赖变成一个单一请求发出去(当然服务器也要支持对这个请求做响应)。

透明的预编译操作包括:

  • templates
  • i18n
  • i18n in templates
  • configurable apps
  • multi-profile apps
  • coffeescript
  • less.js or sass or jade or what ever

这些预编译和运行时优化帮助提升编码者的体验,在预编译阶段可以为浏览器和其它环境做动态适配。

作者总结用Require.js的主要好处(这里其实主要指的是plugins机制):Happiness, Speed, Modularity, Magic

作者后来被问到Require.js会增加http请求对于mobile web怎么办的问题。Alex说在最终部署的时候是要有真正的预编译阶段的。这和Rails的asset pipeline是类似的,在开发的时候方便看到到底是哪个文件的哪一行有问题,但是部署的时候可以通过预编译减少请求。

另外一个问题是Module切分的粒度的问题。Module如果划分的比较细的时候依赖的声明会非常长,比较靠谱的解决方法是通过plugins进行动态注入依赖。但是多个相关的文件被分在不同的Module并主动声明依赖的时候需要平衡这个粒度问题,这是个个人问题,不过由于粒度不容易掌握暂时还是一个没有定论的问题。现场很多大牛表示自己的项目切分的粒度比较粗,这样不需要在不同的文件中跳来跳去,而且强依赖的逻辑块放在一个文件暂时还是天经地义的。

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.