其实我们的前端架构还远未成熟,可以说正在传统前端架构到现代前端架构的转变中,这个转变以引入构建系统为标志(虽然之前mobile版已经引入了stylus),从去年(2014)年初开始,预计可能持续2到3年时间达到一个我心目中理想的较稳定架构。
之所以预期如此长的时间,是因为总体上,对于前端构建、模块化、组件方案等非常基础和牵一发动全身的设施,我采取宁缺毋滥,看不清楚就先不上的保守策略——是不是看上去似乎和我在社区老是讲新技术的形象不太相符?^_^
这种策略有三个原因。
第一是百姓网的性质是以信息流为主、面向所有网民的、平台级的互联网服务。凡此种性质的网站,技术选型的策略总是偏向保守的。相对来说,以体验为主、面向相对小众群体、限定于特定领域的应用,可以更快的采用新技术。像我们的内部系统就会更多采用新技术。
第二,也是更本质的原因是,架构不是光决定用个什么系统就行的,而是牵涉方法论、工具、流程乃至组织结构等诸多层面,是需要整个团队共同理解、实施、维护和不断改进的。团队前进,架构前进。这需要耐心。
第三,百姓网的前端团队在建立之后很长时间里包括我只有3个人,主要精力都在业务上。(当然我们许多后端工程师甚至PM都附带前端开发技能——别以为我在讲段子以下绝壁是真的之我们的CEO三年前就自己玩Meteor并去硅谷见投资人时顺便去参加nodejs的workshop还带着财务总监&我们财务总监当场只完成了helloworld表示不服回来后买了犀牛书问我学JS是不是看这本就好之看你们以后谁敢在我面前自称技术型公司。)期间虽然有尝试改变主站的一些开发方式,但是因为各种原因而无疾而终。去年我们的前端工程师终于超过了10个人,不过和快速增长的业务相比还是远远不够。因此虽然从去年第二季度开始成立了前端架构组,但我并不急于引入各种新设施, 因为我认为对于我们这样规模的团队,资源的冗余度是很低的,走弯路的代价比较高。我要确保每项引入的设施都是正确的。(BAT这样规模的公司就好一些,可以有多个团队同时实施几种不同架构方案。我就指着他们帮我们这些中小型公司探路了,所以我见到他们的人就鼓吹他们快上新技术,呵呵。)
无论如何,今年会有几项重要的前端架构的实施,比如我预期今年要上ES6!大家可以注意到我去年12月的C4(http://weibo.com/1960954893/BBKpY8uq3)和今年1月的FEDAY上讲的内容(hax/es6-in-action · GitHub)就是ES6。这回是要玩真的哦。总之,希望能稳健的前进,到明年这个时候再来看吧。
针对具体问题回答如下:
Q: 百姓网是否使用了 sass / stylus / less 这类预处理工具 ?
A: 百姓网mobile版用了stylus。最新一版重构是基于 @CSS魔法 开发和维护的CMUI/CMUI · GitHub。桌面版因为开发历史比较悠久,一直没有引入预处理工具,短期也不会改。但长期来说最终应该会引入的。
Q: 百姓网 js 模块化开发是如何组织的,是否使用了什么模块化工具、框架?
A: 与大家预期可能不一样,这块我们仍然停留在刀耕火种阶段。百姓网历史上,页面中脚本一直用得不多,虽然很早以前 @sofish 就考虑过引入如seajs的可能性,但是实践上,粗放的脚本合并和一个简陋的按需加载(http://s.baixing.net/js/global/defer.js)也就够用了。不过随着开发规模的增长,当然早晚是要走向更成熟的模块化方案。所以去年年初就开始评估和试验各种方案,比如新开发的某些独立性较高的功能组件是基于commonjs+browserify的。总体上,因为我预期所有模块化方案最终要统一到ES6的module/loader上去,所以基本上想直接上基于遵循ES6语义和API的loader的方案。但是ES6的module部分定案和实现比预期的慢,loader规范也被postpone到独立spec中。估计今年第二季度之后会引入模块化方案。需要注意的是,模块化主要是为提升代码的可维护性,侧重开发阶段。而侧重部署的模块加载或一般化的资源加载相关领域其实还有大量的可能性要探索,仅制定中的标准草案就有HTML Imports、ServiceWorker、Packaging on the Web、HTTP2等,我们需要在架构上厘清这些不同的组件是如何协作并构成整个体系的,这对于未来Web网站和应用的整体性能提升会有极大价值,也是个长期任务。
Q: 具有完整的 html css js 代码片段的 component,是如何 include 到各个页面里的,include 时对 html css js 分别进行了哪些处理?如果这其中的 js 又依赖于某更基础的 js 模块,这个依赖是如何处理的?
A: 和上一个问题类似,由于历史上百姓网的结构比较简单,所以一直没有引入任何一种确定的组件方案。除了需求不是特别大之外,相比模块系统已经明确会统一到ES6,组件系统目前仍是完全不明朗的情况。从维护角度说,模块系统其实转换成本并不太高,组件系统就复杂多了,要从某种 组件系统切换到另一个组件系统听上去就很恐怖。此外,目前业界流行的MV*组件框架绝大多数是纯浏览器端方案,在百姓网主站这样以信息流为主、SEO必需、有较高浏览器兼容性要求的网站来说,无法直接使用。目前业界缺乏能很好的统一浏览器端和服务器端的方案,这是类似百姓网这样的中大型互联网网站少有直接引入类似MV*组件框架的原因。尽管目前没有确定的计划,但在内部系统和不涉及主站的新项目中会鼓励团队成员尝试新技术和方案,目前有少数内部项目已经尝试了Angular。大型Web应用中,组件化的需求是不可避免的(如 block 和 include 协作问题 · Issue #38 · baixing/jedi · GitHub),只是最终的答案可能要再过一段时间才会浮现出来。
Q: 开发环境的代码在发布上线过程中做了哪些处理?
A: 我们有一套PHP写的deploy系统,前端资源的编译、压缩、版本化、替换路径等步骤都是该系统执行的。从去年年初开始我们引入了gulp来进行mobile版的前端构建,会逐步将前述步骤移回到gulp工具链中,并增加更多的处理,比如图片优化和模块打包。desktop版今年应该也会引入。
Q: nodejs 在百姓网技术栈中承担了哪些任务?
A: 前端构建阶段的整条工具链是完全基于nodejs平台,这个自不用说。在线上服务中,部分日志系统是基于nodejs,并且计划会进一步将更多涉及前端的日志系统迁移至nodejs。另外我们使用的第三方服务如LeanCloud的消息服务估计是基于nodejs平台的(虽然与我们无关,但是因为这个服务我们是首先吃螃蟹的用户,它本还没有js sdk,我只好亲自搞了一个hax/avos-chat · GitHub,所以顺便说说)。我们的后端是基于PHP的,但我们并不排斥其他平台,如我们的新业务线也有采用基于python的系统。内部系统也有许多基于nodejs平台,并可能采用新的app框架如Koa。主站系统部分(特别是表现层)迁移到nodejs平台从架构层面来说也一直是可选项。目前的障碍更多的是在较缺乏有nodejs运维经验的工程师,有兴趣的同学欢迎投递简历。
以上。