一个专业的『前端工程化体系』是如何建立的?

原问题:一个专业的『前端工程化体系』是如何建立的?

原问题描述:从技术选型到研发到优化、监控、运维等等一系列体系是如何建立起来的?

在知乎上看到了这个问题,我试着按自己的经验去回答了一下,下面是回答内容:

没在大公司工作过,按题目里的几个名词逐个说点自己的看法。

写在前面:工程化以工程化(易维护、易拓展)为核心,不以性能为核心目的(冒泡排序改成快速排序这种不是工程化的事情)。

一、选型

一般的公司用主流技术栈就行了,别搞太小众的,也别自己搞一套太特异性的,不然一来是给新人熟悉项目结构增加了麻烦,二来也给招人带来了难度,换做是我去应聘一家公司,在待遇等方面都大同小异的情况下,我是不会去到这样的公司做这种项目的,君不见那么多公司都要求面试者要熟悉某某框架某某UI库?如果公司项目不用这些,为了自身发展,员工等于需要变相地花其他时间去熟悉那些东西了,研究那些小众技术基本没有研究主流技术带来的进步大。现在主流的技术选型大致是四种吧,vue, react, angular和传统jquery式开发。说个真实的事,有一次我面试过一个人,他的项目经历里有用vue开发过一个企业官网性质的项目,不是SSR服务端渲染的,是常规客户端渲染的,这种技术选型就太离谱了。需要考虑搜索效果的网站,主要渲染工作应该放在服务端,像后台管理系统这样需要避免被搜索的,或者微信公众号项目这样不care搜索效果的,则只要你的技术选型能带来比较好的模块化开发体验问题一般都不大。如果是要避免被搜索的,一定记得写robo.txt,很多人好像都不写的?
选型需要考虑团队的平均水平,既要避免无法提供团队成长的机会劣币驱逐良币,也要避免选型难度过大到时候有问题没人能解决(所以啊,别弄太小众的技术选型)。

技术选型还要考虑开发效率问题,如果现在这个年头了,选型选的大家还需要写以前那种html, css文件,那简直是在谋财害命。html可以用pug来写,css可以用scss这种来写,这两种按缩进来书写的我感觉基本上是对手写代码量要求最少的了。构建工具(gulp、webpack)肯定要用起来。

二、研发

需要团队统一编码规范,尤其是JavaScript的代码规范,用各种lint来约束即可,配以文档加以简要说明,我觉得这种规范重要的是统一,直接定就可以,不太需要团队讨论,因为这东西基本众口难调,而且像末尾加不加分号根本无伤大雅,要的只是统一,有不合理之处的话另当别论。如果是旧项目,可能不方便一次性调整完所有文件的代码风格,除了直接eslint fix(不确定风险大不大,不建议)外,可以尝试在git的commit钩子上配一下代码风格检测——我的意思是说只对当前要commit的内容进行代码风格检测,这样不会影响到旧有代码,随着业务的更新,慢慢地就会把项目大部分代码的风格都统一起来的。

如果团队成员不太排斥的话,最好上typescript或者flow便于类型检查。

代码要配有适度的注释。

另外个人比较建议上一份大体的业务流程文档方便新人熟悉项目,找代码三小时编码三分钟简直mmp。

代码需要注意抽象拆分,这样方便后续代码的维护和重构,当然也方便测试。如果抽象做得好,会有很多东西最后可以拿出来开源的,如果一个团队的开源做得好,他们的业务项目也不会差,这是一个良性循环。

如果团队有一定规模,并且有人力能抽出来,尽可能要做代码审核。要创建一个和谐的研发氛围,定期的代码审核和技术分享都是要的,要鼓励新人老人们分享技术和经验,不然光写业务代码实在太无聊了,人会跑光的。

三、优化

只要页面加载时间和其他请求的等待时间不至于太长的话,一般不需要考虑优化,不要犯一些诸如遍历ul > li操作dom(应该把ul里的html片段字符串对应改动写好后直接替换,这样只操作一次dom)的问题就可以了。基本的优化点想到的有这些:
静态资源压缩(js、css、图片等)+CDN(浏览器对单个域名的静态资源有并行下载个数限制,把静态资源挂在多个二级目录上,就可以增加并行的静态资源下载数了);

减少直接的DOM操作(DOM操作开销非常大);

dom操作语句尽量写到一起,不要分开,据说这样可以利用浏览器自身的优化功能;

可并行的http请求不要顺序发送;

一些请求可以考虑静默发送;

频繁触发的事件(比如滑动事件)对应的handler如果随着事件发生而高频率执行,也是非常不可取的,可以考虑函数节流,让handler不要执行得这么勤快;

减少明显不需要的冗余代码(除了自己写的代码外,常见的比如同时使用jquery和axios。。。);

四、监控

监控的话看过几篇文章,大体思路是ajax错误处理里对发生的错误按一定比例取样上报(发请求到服务端),要发送的信息包括请求的地址、请求参数和请求头、响应参数和响应头、当前页面地址、用户设备信息(UserAgent、屏幕尺寸等)、当前时间、用户id等你觉得需要的信息。这块我尚无实践经验,就此打住。

五、运维

运维运维,运行和维护。

编译本地项目、发布到服务器、在服务器上启动服务,这些操作一定要通过命令/脚本执行,并且还需要写一份check list,不能靠记忆和人力手工执行,因为人为操作,总有疏忽的时候,比如【忘了编译直接就发布了】。

如果是纯前端范围的话,由于都是静态文件,发布后的运维还是比较简单的。发布方面,npm里有个叫gulp-scp2的包,可以在有ssh账号的情况下很方便的将本地文件发布到服务器上(特意去开个发文件用的SFTP工具就显得有点麻烦了)。npm上还有个npm-run-all的包,可以很方便的将package.json的scripts中的多个命令进行串并联组合,在本地弄一些命令的时间比较好用。
如果涉及到node服务的话,可以用pm2进行发布。pm2有对应的错误日志的,如果服务挂了,看错误日志一般能找到问题所在的。pm2 status 这样一个简单的命令,就可以让你看到一些诸如重启次数、CPU占用、服务当前状态等有用的信息。

当然你还应该在服务出故障后往一些人的邮箱里发提示邮件,发邮件我还没尝试过 。