从帝都到杭州后,便开始不停的更新自己的workflow,直至今天都不能让自己完全满意。尤其是最近这段时间写东西写的十分焦躁,因为许多事情,不能完全沉浸。

其中一点便是希望开发环境可以更加的顺手。

双十二之后,专心折腾了一阵开发环境,在继续深耕细作之前,想了解一下大家都是怎么做的,于是便有了知乎上的疑问贴。

说到开发环境,不得不提团队所建设的基础设施,出于协议约束,提大家在会议上都知道的事情好了:

我所在的团队有相对成熟,并且久经考验的框架,并配套了一堆组件。一般情况下,前端开发人员,只要遵守一定的开发规范,代码可以很容易的在构建之后发布到线上。并且团队为了降低协调成本,从之前决定的在提交前对代码进行lint变为中心机进行构建,保证了代码的一致性,甚至cdn对于资源的protocol都做到了无缝切换。如果对图标sprite表示厌烦,集团还有iconfont可以用,代理/mock工具一应俱全。

那么,为什么还不满足呢? 实际上,一线前端所接触的业务环境远远比想象中的复杂,举几个例子:

单人开发完整项目 && 前后端联调 && 冒烟前的自测

  • 一般来说,需求评审之后,大家就会撸起袖子开干。
    • 但是PRD中隐藏了大量工作量:“和线上保持一致”但是并不能直接使用的(因为代码耦合甚至基础库依赖的问题),甚至要重写的组件、“和习惯保持一致,但是大量被忽略的异常”(这里要截断么,当然你可以使用冗余一点的代码,保持最佳扩展状态,如果你愿意)、“忽略的,但是需要为后端鸭梨而考虑的缓存”(延时、缓存、请求限制)。
    • 或许你会这么想:好坑啊,做完到是没什么,可是自测怎么办,交给专业的tester真的不会疏漏什么么。
  • 接口约定。
    • 前后端简单约定接口,前端进行实现,你会发现后端接口可能无法确定字段,以及线上的字段多多稍稍和实际不同。不论是因为你们是“新黄金搭档”的缘故还是“后端根本不了解前端需要的是什么”,抑或“XX字段没法这样给你”。
    • 或许你会想,早点让后端看到我的接口字段的JSON格式就好了,在我开始做的时候,他早点发现问题,早点告诉我哪里可能要变就好了。
  • 项目开发
    • “日常环境还没好呢,稍等下啊,我重启了,稍等下啊,我临时中断了”、“这个接口日常没有,得用线上”、“这个接口得用测试帐号登录”、“这个接口限定XX域”、“你必须初始化组件A,B,C,D,E,F,…Z,然后就可以轻松的获取某个变量,然后揉成一团,踢到后端,结果就对了”、“身体不舒服,在家里写(VPN连上发现接口不能访问..damn)”
    • 当你因为某个接口不对,然后改花程序的时候,发觉是别人在做在线调试…呵呵呵呵…
    • 其实愿意告诉你缘由的人,都是好人,你或许会遇到事不关己高高挂起的人。其实你本不该翻工做许多事情的。这个时候,你会不会期待你的开发环境单纯可靠。
  • 联调测试
    • 交给tester后,修不完一堆你没注意到的bug,接着真的万无一失了么。too young,大促当天,随手翻动页面,发现好多bug,还好有在线开关,可以临时关闭,紧急修复,不然…
    • 测试们也有好多活并行,而且前端代码一般情况下他们是不会去帮你review的,更何况写测试脚本去搞你的异常复杂的交互行为的测试呢。
    • 这个时候,你或许会想,如果早一点,我在做的时候,就能很方便的切换所有接口的组合,把分支覆盖全了就好了。
  • 发布代码
    • 代码发布了,高枕无忧?“诶,你的代码怎么没正确运行?”、“卧槽,combine后的关键字有ad,被adblock日了”、“构建结果和我本地不一致啊,构建结果把XX优化掉了,卧槽,模板方法不支持XX版本的基础库”。
    • 你会不会怀念本地调试,而非代理调试的日子。
  • 后期维护
    • 间隔了几个月后的修改,“诶,这个模块的逻辑怎么不对了,导出函数的结果明明应该是X,怎么是Y。”
    • 有没有后悔没有上测试用例呢。
  • 项目交接
    • “这个是新来的童鞋小白啊,这个项目,以后就是他负责了,抓紧时间了解一下”
    • “这个是新来的童鞋小白啊,这个项目的制作人大概一周后就走了呢,你要抓紧时间了解一下”
    • “这个是新来的童鞋小白啊,这个项目要翻工重做了,之前有四五拨前端都做过呢,抓紧时间了解一下”
    • “这个项目很简单的,你npm install就好了,这个项目很简单的,你只要A/B/C/D/E/……”
    • 然后当你望着没有demo,没有doc,只有一团团被随意粘贴的到处都是的代码,以及换个操作系统可能跑不起来的编译环境…
  • 如果你要交接给后端
    • “能不能不要压缩,能不能不用你们复杂的框架,这段js copy进来为啥不能用…”
    • “你们的发布这么复杂啊,git不会用啊,我们用svn…”
    • “哦,还要安装node啊,我是windows,有个东西编译了好多次都失败”

你会期待一个相对完整独立的开发环境么,不用在本机上安装乱七八糟的一堆运行环境,可以支持简单的mock,可以根据自己的情况随意切换数据接口版本,即使后端翻脸改接口,也可以轻松直面接口,而不是若干回调后的接口。即使交接,也是轻轻松松的。

单人开发组件模块

  • “你的模块独来独往”
    • 肆意发挥吧,请注意单人开发完整项目中提到的事情。
  • “你的模块需要和其他历史悠久的模块珠联璧合”
    • 可以顺利的:默认按照之前的模块的行为来,特殊情况,按照PD大人的吩咐。PD大人没有吩咐的,参考单人开发完整项目
    • 需要将原来的模块包裹在你的模块里,“OMG,这个老模块这样实现不对啊,这样…这样…这样…诶,还得把模板和gruntfile(gulpfile)改掉”
  • “你的模块的兼容性有问题”
    • 浏览器的问题不光是语义兼容,还包括了基础类库的api兼容,不同的页面的基础类库的版本不同,差异可大可小。
  • 最后,你得进行自测,测试范围,不仅仅是你写的,还包括你是否能和固有模块搭配得当。这里面如果涉及接口,请参考单人开发完整项目存在的可能性。(老项目接口变化翻天覆地又不是没见过,诸如接入了什么逻辑之后…)

你会期待有一个可以让你在demo页面直接使用线上其他模块而不需要顾及太多接口依赖的开发环境么,你会期待除了你的接口之外,其他的依赖模块调用的接口百分百保持一致,可以在开发的时候,某时刻忽略么。你会期待你的模块可以在本地就完成一次完整的发布预览么(预发环境不是每个项目都有的)

多个前端协同开发业务模块

  • “这个项目,什么时间点之前要完成,先实现”
  • “这个项目这里临时加了XX,抓紧实现”
  • “老大拍板了,这个不做了,我们换做这个,还有X天,大家辛苦了”
  • “诶,那个谁谁没告诉你这个变了么/你不注意邮件啊(各种垃圾邮件把正事淹没于海中)”
  • “等下,别提交了,我们升个版本”
  • “你版本升这么快?改啥了”
  • “你这里等下,我把这里完成了,你更新一下再调用”
  • “XX后端说,这里要变成XYZ方案,所以A && B得变一下,C童鞋你等我们更新了代码,别提交那个文件了,还得合并”
  • “帮我code review下吧,我和谁谁一起提交了。”
  • “卧槽,我merge了一下午build文件,大家提交了多少次,就冲突了多少次…”
  • “xx用的是windows,和我们环境不一样,编译出来的字符有问题”
  • “本地开发构建的和线上不一致,我擦…”
  • “大家提交了commit淹没了之前XX改的bug”
  • “模块A得用grunt、模块B得用gulp、模块C得用XXX…(身未动,心已远)”

这些对话,存在于,两个人到十几个前端的对话中,各种需求的变动,为了省事没有单独开分支,或者因为代码没成型,不适合开分支进行小功能开发,等等,如果有大家有物理隔离,并且能离线协作的方式,会不会更好呢。

离线开发

  • 有的时候,真的想坐在露台,吹着小风写一天。
  • 有的时候,身体不舒服或者临时要远程,但是在远程的时候,发现接口访问不到,或者静态数据和接口不能一起访问。
  • 有的时候,开发组件真的想把所有的依赖接口都简化掉,减少复杂度。

如果大家都只对接口负责,那么开发效率以及沟通成本绝对下降了不止一点半点。而接口变动,只需要对接口数据模块做简单的适配就好(前端后端都可以做,孔融让梨,不太复杂的和不涉及安全隐患,不影响效率的,我们做好了)

DEMO展示

  • “你的DEMO什么时候能看,我得送呈老大。”
  • “你的组件效果是啥,我能看一下么,可以动态改变接口看效果么”
  • “你的项目可以根据动态配置来展示么,有demo么”
  • “大家再等下,接口连不上”
  • “暂时看不到,等后端接口上线后”

如果纯静态环境生成动态数据,引用颇多不说,还要反复造轮子和写不相关代码,为何不把这些交给一个简单的环境去处理(当然也可以中心机,只是离线就做不到了)

多个不同环境依赖的项目同时进行

  • “你A项目的环境用的是node版本是多少、B是多少,能不能同时跑,不mock。”
  • “你用nginx做的代理、线上是nginx和node都用,环境不一致啊,对于某个请求报错了,你看看”
  • “这个模块引用的资源(接口/assets)在这台日常机器上,那个模块引用的资源在那台日常机器上,但是他们的域名地址一样”
  • “本地同时跑的PHP脚本依赖的PHP runtime版本不一样,运行抛错了”

如果复杂的东西可以并存,至少在开发环境可以并存,多和谐。每次,每个人都要折腾环境,环境很受伤的。

项目前后端不完全分离

  • “VM里有HTML和inline script/inline style”
  • “接口返回HTML DOM片段包裹脚本片段”
  • “XX操作提交完毕之后,页面数据得刷新一下。”

这个时候,如果你有一套支持数据分离的开发环境,那么这种代码消亡只是时间问题。如果代码只能随着业务的消亡而消亡,那么太可惜了。 暂时写到这里,稍后补充一些环境配置上的细节。

–EOF–

2015.2.4 晓白