分设重构和前端?我想说...

2,144 阅读14分钟
首先利益相关:某鹅重构一位,之前在小公司是全栈工程师~

今天周五下班早,刷知乎,看到了一个很有意思的话题——

『 如何看待腾讯等大公司前端分设JS与重构两个岗位对公司和对个人的影响?』

里面意见纷纭,有赞成腾讯重构分离的,但是不多。

摘抄个赞同方高赞回答,from 玉伯

“认识腾讯的一些重构工程师,真正了解他们的工作后,我真心佩服。重构工程师的工作,并不是简单的将设计稿翻译成 DOM 与 CSS 代码,更多是会与设计师一起,从技术的手段给设计提供可行性分析、提供灵感、将代码的灵魂赋予设计。这份工作并不简单,对前沿设计的关注,对 CSS 技术的敏锐,对 DOM 最优结构的追求,还拥有着一双与设计师一般敏锐的像素眼(很多码农缺失、很难培养),以及对美的天然感知力(天然的背后是多年的设计感知积累),很赞这么一帮游走在艺术与技术之间的人,给世界增加了很多美好产品的细腻实现。很尊重这么一帮人,我心目中的重构设计师。”

而更多的是赞成前端往全能的方向走,比如阿里的几位前端,都有提到阿里的一种趋势,『将前端工程师改造成全栈工程师』。还有一些前端同行,也是提出了重构以及前端JS工程师的割裂,势必与现在的潮流相违背,而且两个岗位的定义、分工都存在一定的模糊地带,强行分开只会增加沟通的成本,以及双方为了merge代码,修改缺陷的一大堆撕逼,反而对设置重构岗位时效率提高的预期,造成了相反作用。

也摘抄一下反对方的答案吧,from 贺老:

“实际上,我接触过的一些重构岗的同学对用户体验的认知过于狭窄,很多只停留在视觉、排版和动效上。不是说这些不重要,但是真正大的方面,比如信息架构、交互流程之类的,根本就是重构岗职能和技能以外的东西。反而是正常前端岗有能力掌控这些。”


另一个答案 from Jim Liu

“”生产流水线变长,沟通和返工成本增加
这个是最致命的,尤其是,当页面交互多起来的时候,重构实现了交互原型,前端要把它和自己的代码做一定程度的merge,您总不能保证,每一个组件,都是解耦得如此完美无缺吧?然后,界面上一有风吹草动,就意味着可能需要重新merge,真是遭不住啊……”


我的观点?

虽然我现在是重构,但是我坚决地支持,重构、前端,不应该分开!

为什么?

在回答为什么之前,先请各位读者在心里回答几个问题(逃)~

  • 为什么有前端?前端负责的是什么?
  • 为什么渲染一个页面要分开为JS、CSS、HTML?
  • 为什么React要用JSX以及它提倡的CSS in JS支持和反对的两派都好像很有道理?





前端,在很久很久的以前,俗称切图仔,写下CSS,切下设计稿,用用jq,就可以写个大概能看得过去的页面了,当然厉害的前端大神也能用原生js玩出花。。。这算前端的“刀耕火种”时代吧,非常地原始,效率也不高,而且前端长期挣扎在IE6兼容啊什么鬼的问题。。。但是此时,也是重构和前端分离最自然而然的时代。重构切好图,写好CSS,出个静态html,剩下的就是让JS同学,自己管理数据渲染。想象一下,写后台的同学,操着bootstrap来做OA系统的画面,就是那样(逃


到了三四年前,Angular的横空出世,算得上第一个知名度绝高的MVVM框架吧,双向数据绑定等新特性,跟以前JQ动辄就是自己写个pub/sub轮子,手动操作DOM的笨拙姿势,新框架带来的无疑是观念上的极大改变,从操作DOM到了操作数据,而重构出CSS的方面也是如同jq时代一样,和JS方面井水不犯河水,甚至还因为 Angular减少了操作DOM的必要性,也减少了DOM结构变动导致重构出稿的效果不明显、效果冲突等问题。

2015年至今,最热的框架不再是Angular和jQuery,转而变为了React和Vue两家。(因为我之前主要写react,vue只是照着文档写了个demo,所以vue的篇幅不会太多,对vue的理解如果有误,请多多指教)

React革命性地提出了Virtual-DOM的概念,JSX看似模仿HTML的嵌套标签语法,其实是全新的思路,前端工程师将以前的HTML DOM结构写到JS里面去,让React去接管生成,重绘,优化。所以React+Redux全家桶可以做前台数据管理,也可以脱离浏览器环境,由node server进行服务端渲染。这就是新的思路,既然大家都在给DOM的优化弄得死去活来,又不想用smarty CI这种PHP JSP模板来后台生成页面,我用JS不就好了?

既然HTML都可以做到JS了,那CSS呢?是不是也可以做进去?

React大家还习惯于写HTML,所以css部分还是沿着原来的习惯,编译好sass/less,用react className去对应选择器的CSS文件寻找样式,但是且慢——

React Native就不一样了~

以下代码为FB官方开源 F8 APP 源代码:


握草!内联样式!妈妈说过CSS要和HTML分离的!不能这样写啊啊啊!!!

这就是新的写法,CSS IN JS!

看下FB官方认为React Native一个标准的组件代码是怎样写的:

首先,引入外部JS组件:

然后,初始化react component,定义下默认props,states,proptypes:

渲染步骤,熟悉的一层包一层的JSX组件。。。但是可以手动控制渲染条件什么的

样式,用一个JS变量保存:

做过APP的无论是原生安卓/iOS的同学,还是做RN/H5 SPA的同学,都得承认,页面的区分尺度就是每个不同的页面,细分起来就是toolbar组件啊,sidebar组件啊,button组件啊。React的Component机制,加上JSX的嵌套标签语法,完美地切合了这种需求。前端工程师只需用组件像堆积木一样地堆出一个页面,然后根据不同的后台数据组装显示不同页面,就达成了页面的逻辑计算以及样式展示。


这和普通的重构写CSS样式然后按页面切有什么不同呢?

  • React Native:页面元素组件化,样式在各自的组件维护单独的style,不涉及全局变量
  • 普通页面:页面元素以DOM元素区分,维护一个大的公共CSS(如Bootstrap),元素根据CSS选择器获取样式

读者可能说差不多嘛,一个CSS跟JS一起,一个分离出去,有很大差别吗?


有。


如果写过大型的CSS的同学,一定都会对CSS的命名有一套自己的规则,比如著名的BEM(BEM的定义),写一个不重复的类名,你都要遵照非常严格的标准,还要全局搜一下有没有组员的样式重名了,再加上写SASS的同学常用的嵌套,&语法,就更加可能重复了(why-using-bem-for-your-css-is-a-bad-idea/)。

---长得不行的类名。。。

如何避免重复呢,组内规范啊,尽量用有语义的长名字啊,不觉得很悲催么,宝贵的时间都花在命名了。可是,为什么CSS命名就要避免重复?

因为CSS选择器是全!局!变!量!

相比之下,写JS的同学实在是太幸福了(开始走题中。。。)

  • var变量很多坑是吧,ES6加上let(块状作用域),const(常量用)
  • 写轮子要在原型链上写太累,我想找个简单的方法整理代码,ES6就加上了class
  • 匿名函数的this也有坑啊,不手动bind经常会掉链子啊,所以,有了箭头函数()=>{}

还有很多很多的新特性在JS语言中逐渐添加,前端的同学只要配个gulp或者webpack加上babel,就可以欢快地在IE9以上的浏览器跑新语法的代码了~


然而写CSS的苦逼同学,他们只能默默地打开一个亲爱的网站

--- http://caniuse.com

开始查询新参数可不可以用,没有用就要想办法hack,或者做降级兼容,为什么?

因为css没有babel,sass也没有tree-shaking(Webpack v2和rollup.js都支持js的tree shaking了)

所以CSS新特性用不了,sass的import如果在多处地方同时引用也会有严重的重复引用问题(不能像webpack的js module一样相同模块只会复制一次)

岔开一句话,CSS Secrets是一本所有想做好视觉效果的前端必看的书,里面运用了很多CSS新特性,只是你工作上可不可以得到这么牛的浏览器支持,产品经理会不会因为你的效果在客户手机上broken了手撕了你,那就另外一回事了(逃


说了这么多CSS的坑,再说回来刚刚没提到的Vue。我虽然用得不多,但是无论是鹅厂,还是饿了么,阿里,还有无数的创业小公司,对Vue都是特别地青睐。

Vue在设计,源代码上的优雅我就不说了,了解不深,知乎,掘金也有很多分析的文章,大家可以去看看。普通的前端选择它,我采访了几个同行,大概可以总结为以下几个观点:

  1. 官方文档齐全,有中文版
  2. 开箱即用的特性,Vue虽然轻,但是结合API和文档介绍,可以很快上手做个小项目,代码也保证了质量
  3. 即使不满足Vue的轻,还有很多Vuex,Vue的服务端渲染插件,weex等社区轮子可供调用
  4. Vue可以只负责JS 逻辑部分,HTML和CSS分离,互不干扰。


注意一下,这里的第4点,跟React和React native还是有很大分别的,虽然Vue2.0也增加了virtual-dom的特性,但是它平时HTML和CSS、JS的分离,实在是方便了很多重构同学。重构同学又可以愉快地仅输出HTML和SASS编译过后的CSS,然后让JS同学继续剩下的部分。所以,重构同学较多的公司,对Vue的支持会更加热烈~

但是!

Vue也不是如同jQuery一样,html完全是无侵入的,仔细看文档,有v-if等语句的用法,如果是纯重构不懂vue的话,是不知道如何下手运用API,减少JS工程师的工作量。而输出纯HTML,而没有运用这些特性的。反应到重构和前端的合作,往往需要前端重新走查代码,加入vue的标识字符,导致效率的降低

同时,Vue 2.0的服务端渲染,也是一个新特性,它的诞生是因为vue 2.0也引进了virtual-dom的机制,因此,vue还甚至破天荒地提供了用react的JSX语法来写vue的这种混搭组合(笑)。要做到服务端渲染,就要抛离原来的DOM结构输出,改用vue的template以及vue组件写,这里如果是不懂JS的重构同学,对此就爱莫能助了。

---------------------------------------一条华丽丽的分割线---------------------------------------

上面说了四种流行的框架,分别代表了前端的三个时期。可以看到,在以前的jQuery和Angular时代,重构和前端的分离还是比较自然的,两者的分工也一定程度上提高了效率。但是到了新时代的react和vue双雄争霸,React的提倡CSS IN JS和JSX的Component写法,以及vue同样的为了SSR的模板以及自定义标签的DOM结构的改造,都对纯粹的重构以及JS工程师发起了冲击。重构不懂js,前端不精通CSS,两者的磨合问题将会一直持续下去。

总结一下在分设重构和前端的公司下两者分别的优缺点吧:

纯粹的重构(只懂CSS的):

  • 优点:和设计师磨合程度好,减少了前端同事和设计的撕逼时间,有充足的时间研究如果最大还原设计稿,
  • 缺点:不懂JS,在参与RN、React、Vue等新型框架的编写,设计的组件是基于设计师的角度,无法与前端同事需求完美切合,前端需要重新改造组件,时间成本高,并且组件化的选择条件切换渲染,对于重构同事的组件内样式编写,是一个新的挑战

纯粹的前端(只懂JS的):

  • 优点:因为大幅度减少了重构花费的时间,可以把更多精力放在优化性能,搭建平台,数据控制、绑定的方面
  • 缺点:不懂CSS,在遇到不同子组件切换渲染情况,以及需要重新设计组件方便调用时,可能与重构稿效果不同,要通知重构重新给新的CSS,降低了工作效率

最后最后,一点小看法

现况如同贺老的回答一样,前端要学CSS,即使算上sass、less,bem,canvas动画等等,也可以很快上手。但是重构要达到一个JS工程师必须的水平,要做的改变非常大,因为本来偏的是设计路线,对整个CS的软件体系,JS原理,坑等等都要懂,不是几个星期的事儿。 在现实也接触到不少重构,工作了5、6年连setInterval也不会用,这就很尴尬了。还有在现在很火的React Native,就像上文讲的一样,是一个CSS和JS非常关系紧密的框架,很多原来写Angular与前端配合的重构,发现自己不学JS不学React就要被淘汰了,连写个样式表都无从下手。写RN前端的同事也很烦恼(我之前也在写RN前端。。。),RN究竟要不要让重构的同事参与进来,自己写样式还快多了。。。同时,因为JS工程师可以涉及的面更加广阔,从控制动画,到逻辑渲染,后台数据拉取,node微服务,思维也是CS那一套,对于交互流程,优化,缓存都有更加深刻的理解。

而重构,完全就是一种熟能生巧的活动。至于有同行得意洋洋的“像素眼“,“IE6兼容”等等的,确实是重构有能力,有毅力的一个表现形式,但是,脱离了生产环境的思考,过于追究设计上的美与还原度,未免思路过于狭窄,不像一个程序员了。

因此,我更加认同的是,title和分工是公司分配的,但是个人的奋斗还是要看自己的。一个优秀的前端,JS也要学,CSS也要学,对于新知识的敏感度,对于自己每天的代码的思考,如何写更优雅,更完美的代码,还有减少首屏时间,上HTTP/2有什么优势诸如此类的优化想法,这都是值得每天工作之余好好思考的。也许,那个时候就不会纠结于自己究竟是全栈还是全干了(逃