一个 32 岁「老」码农的复盘:崭露头角

本文首发于 欧雷流。由于我会时不时对文章进行补充、修正和润色,为了保证所看到的是最新版本,请阅读 原文

本系列上篇文章《一个 32 岁「老」码农的复盘:初出茅庐》中讲述了我通过两段共计三年左右的工作经历入了行,大致了解了「前端工程师」这个职业以及软件开发行业的大概面貌。虽然我自身的问题占了一部分原因,但我认为它们在一定程度上限制了我的成长速度——

选择到什么样的公司去工作是一件需要万分谨慎的事情。进错公司毁一生,我不是在开玩笑!不要小看人性的弱点和环境的作用。

——欧雷《一个前端的职业轨迹

在本文所述说的工作经历中,随着工作环境的改善,我也开始有所转变——

刺暮软件

2013 年 3 月下旬,我入职了一家「做软件」的公司。之所以用「做软件」这个词,是因为这家公司的构成和关系略微复杂,且听我慢慢道来——

我签合同的公司是「刺暮软件」,公司的业务是做一些外包性质的移动端应用。然而它并不是外包公司,应该是为了存活的临时业务。这家公司的创始团队皆来自 2K 中国,即 2K 的中国分公司。

在发展的过程中,又成立了两个「子公司」,分别是做在线教育的「有渔教育」和做游戏的「黑火游戏」。虽然我的合同是签在「刺暮软件」,但做的事情由始至终都是一个叫「有渔」的在线教育平台。黑火游戏的代表作有《符石守护者》和《元能失控》(这个游戏的制作者变成了「火花工作室」,但人是同一拨人)。

另外,不知为何,刺暮与杉果游戏也有所关联……

一个 32 岁「老」码农的复盘:崭露头角_第1张图片

我所参与的在线教育项目,起初是面向中、小学的翻转课堂,以「贴牌」的形式给杭州本地的学校定制系统,如:杭州市采荷实验学校杭州第十四中学;后来以 SaaS 形式走平台化路线,就变成了「有渔」,它的功能是围绕着「课程」来展开的,除了课程,有任务、习题、问答、组织和社交等功能模块——

「有渔」是以国际化视野打造的翻转式学校,提供英语、创意计算、机器人等国际先进课程的翻转课堂教学服务,以及「翻转课堂」、「黑板报」等云端软件服务。

作为最新一代网络教学系统,「有渔・翻转课堂」融合了 MOOC(大规模在线公开课平台)、SNS(社交网络)、游戏化教学、数据化分析、百科等先进教育理念,通过 SaaS(软件服务)模式构建,旨在打造中国「翻转课堂」第一平台,为学校、企业、名师、个人等提供人性化、信息化和定制化的教学云服务。「有渔・翻转课堂」始终本着「让教者乐其教,让学者乐其学」的服务宗旨,从教、学、监三个方面综合设计,着意教学管理与学习交流相结合,立足三大角色,开创五大功能,兼摄四大优势,主张开放思维、自主教学、互促互进,最终实现和衷共济、教学相长的数字化创新教育。

——忘了从哪看到的介绍

平台的用户分为「学员」和「教师」两种身份,前台页面都能访问且没有差别,后台页面根据身份的不同会有所区别:学员是查看自己在学习的课程、在做的任务、错题集、参与的问答、加入的组织和好友列表等;而老师则是进行课程、习题、任务等的管理。该平台除了 PC 端 web 页面,还有 iPad 客户端。

一个 32 岁「老」码农的复盘:崭露头角_第2张图片

由于这里采用的 web 框架是 Ruby on Rails(下文简称「rails」),所以前端方面的技术选型也是以与其结合较好的为优先,如:CoffeeScriptSassCompass。rails 不了解倒无所谓,但无论是 CoffeeScript 还是 Sass、Compass,都是之前听都没听过的,需要从头学起……

虽然产品线相对单一,功能没有十分复杂,但毕竟算是个互联网产品。并且当时 AngularJS、React、Vue 在国内还没火起来(我刚到这家公司时 React 和 Vue 还没问世),复杂应用框架主要是 Backbone 比较有名,jQuery 依然占有很重要的地位。

在这期间,结合工作实践,我造了好几个轮子(玩具),基本是用 CoffeeScript 和 Sass 写的:

名称 说明
Painter(现在叫「Trick」) 工具类 Sass mixin 库
Tangram 布局类 Sass mixin 库
Ronin DOM 无关的 JavaScript 解决方案、增强库
Miso 用于对 JavaScript Plain Object 的每个成员函数的实参(arguments)进行合法性校验以及统一返回值(return value)的「批处理器」
Tatami JavaScript 工具库(乞丐版框架?)
Matcha 一个 UI 库,包含了 Painter、Tangram 和 Miso
Video.js Progress 基于 Video.js 的进度条增强插件
Video.js Track 基于 Video.js 的文本轨增强插件
jQuery Cascading Tabs 基于 jQuery 和 Matcha 的级联选项卡组件
jQuery Pagination 基于 jQuery 和 Matcha 的翻页组件
jQuery Double-list 基于 jQuery 的双列表(穿梭框)组件
H5Fx 基于 jQuery 和 HTML Forms 规范的表单校验插件

虽然这些库绝大部分已经不再维护了,但它们的变体和还在维护的库在之后乃至未来的我所参与的项目中继续产生价值。

随着业务需求的不断增加,页面变得越来越多,资源文件也变得越来越大,导致页面加载速度不断下降,加速页面呈现成为刻不容缓的事情。于是,决定通过 Turbolinks 将网站变成单页面应用来减少资源文件的请求。

需要说明的是,用 Turbolinks 实现的单页面应用与现在大家所熟知的方案有所不同,它完全是运行时的方案:在点击下一个页面的链接时,会先判断那个页面有没有已经在内存中进行缓存,如果有就直接拿来替换掉当前页面 中的内容,没有就会通过 AJAX 拿到页面内容缓存后替换;在请求页面内容阶段,页面顶部会有一个很细的加载进度条;默认最多只能缓存 10 张页面的内容。

项目的运行是基于我写的 Tatami,各种初始化逻辑是依赖于原生的页面生命周期事件,在引入 Turbolinks 之后破坏了原有的「生态平衡」,它改变了页面的生命周期,因而引起了一些较为棘手的问题: UI 初始化异常、事件绑定及触发异常等。

经过几天的调查研究,最后写了个适配器通过修改 Node.prototype 的方法(method)解决了