前言
好久没更文了,因为有很多人问我工程化相关的内容,而我之前的工作中恰好有一些工程化的经验,这里笼统地和大家分享一下(没法太具体,具体的话,每部分都需要单开文章长篇大论),所以这里旨在为大家搭建体系,有需要的话,再慢慢细出吧(比较忙,见谅啦~)
在开始前我问大家一个问题,前端工程化,是什么?
一提到前端工程化就说到webpack
,难道webpack
就是前端工程化吗?webpack
是打包工具,啊,前端工程化就是打包啊?
好的,我知道前端工程化了,就是用webpack
啦或者用vite
打包,然后调一下配置项
,该有的都有,打包分析
、treeshaking
。。。
诶嘛,我还知道treeshaking
呢,加分了!
哈哈哈哈,搞一个小段子~
不知道你有没有上面这样的误区,如果有,我不能说你不对
因为工程化这个东西,它并没有相对统一的规范,每个人或者说是每个公司,每个项目,都去做属于自己的工程化
这是一个摸索的过程,并没有对错之分
而在这篇文章,我就说说我对前端工程化的摸索、实践,也可以说我的前端工程化是什么样的
大家如果觉得不对,无可厚非,每个人都有自己的认知和体系,大家互相学习才是最重要的
我的工程化体系
对我来说什么是工程化
抛去代码,思考一下工程化
这个词
我这里浅浅百度了一下,当然,这几点不一定全面,但是我们看看,这几个点是不是也贯穿在我们的代码开发之中呢
那么我觉得,这些点,不论是这上面谈到的,还是没谈到的,我都想把工程化
的概念和用途简单化
赋能
我们开发一个项目,即是在做一个工程,我们在开发中摸索经验,积累,形成体系,给团队和接下来的项目赋能,让接下来的工作做的更好,那么我认为这就是在工程化
那么在我的开发过程中,我做过一些我认为是工程化方面
的工作,来和大家分享一下,看看有些东西,大家是不是觉得耳熟
评审
需求评审
,一个在做任何一个项目之前的必备步骤
可能大家做的最多的评审就是功能开发
的评审,或者是项目初始开发
的评审,我们会进行讨论
一般会有产品、UI、开发、测试
,这是最常见的,一般来说就是产品和项目经理起草项目文档,产品和UI完善原型,然后进行功能的评审,评审难度、可行性
,从而分出工时
,然后在类似禅道
的平台上分发任务和工时,这样就完成了一个基础的初始化体系
有了最初的体系,下面的任务才能更好地进行
规范
好的,我们已经完成了评审,要开始我们的项目开发了,假设我们这是一个新项目,技术栈已定的情况下(在我之前的工作中技术栈一般是主管定),我们要开始进行项目最开始的建设
项目规范化建设
那这个规范化,我们通常都说那几个方面呢
格式规范化
提交规范化
命名规范化
注释规范化
关于格式和提交规范,我们除了CR阶段
,在日常开发中通常会怎么处理呢
相信大家看过很多文章了,所以这里简单带过一下即可
ESlint、 stylelint、prettier
来处理一些语言的格式问题
配置husky的pre-commit、添加commitlint配置文件
来进行提交的规范化
关于命名的规范化,可能不同的公司的处理方式是不一定的,比如动名词要求
,大小驼峰命名
等,一般会写在公司内部的开发文档
上
关于开发文档这里解释一下
开发文档的形式是不固定的,可能是写在
语雀
、飞书
等文档类平台上,可能是自己通过vuepress
或者vitepress
自己搭建,甚至可能就是写在一个word
上,这都是不固定的开发文档也有多种,我们不去管那些产品层面的
使用文档
,就开发层面上来看,我目前接触的是组件文档
和工具文档
,前者是内部组件库之类的,后者是内部封装的工具库,这二者往往需要结合文档来进行使用和记录,同时写好文档也方便别人来进行观看和更迭,当然,如果你的目的是防御式编程
的话,那随意~但是在我之前的工作中,频繁的定期CR属实是不太方便防御式编程
我们回过头来,除了遵循文档,我经历过哪些命名规范的实践呢,BEM函数
是一个
此方法在组件库项目中最为常用,也是开源组件库项目中比较常用的,因为单纯手动遵循BEM规范的话,属实很麻烦,所以我们借助函数来帮我们完成,大致是,引入定义块、定义元素
- 根元素用
bem()
定义块 - 用
bem('element')
定义子元素 - 多种状态的修饰器用列表
bem([])
- 状态为布尔类型的修饰器用对象
bem({})
- 一个节点
只用一个bem()
具体的实践和介绍可以看这篇BEM 规范及实战快速生成 - 掘金 (juejin.cn)
而关于注释规范化,其实每个公司的要求是不一样的,比如哪些注释是最后保留的,块级注释的覆盖率的等
因为块级注释可以做到更好的提示功能,而且说白了,看起来就有种规范感,领导是爱看的
同时在开发中,块级注释对于函数、对象、枚举、接口
等都是很友好的
最后,关于规范,其实很多大厂是开源出自己的很多规范的,有很多小公司也都是以大厂的规范为主,大致就像这篇文章的介绍一样
推荐几款代码规范文档库,建议收藏! - 掘金 (juejin.cn)
其实还有很多规范,但是我做过的有限,所以不展开说了
工具/自研库/cli/SDK
关于工具/自研库/cli/SDK
的开发,是工程化较为直观的体现了
拿上面的规范化举例,如果我们每开一个项目,都要进行如此繁琐的配置,那么是不是有够头疼,难道每新来一个同事,都要去手把手去教一下吗,显然不是的,这时候我们可以封装成一个npm库
,同时如果有npm私服
的话,可以放到私服
上,供内部使用
当然,有钱的可能都去挂CDN了,不同的预算,不同的解决方式
同时,大家经常会看到一些文章,会觉得pnpm+monorepo
似乎和前端工程化
已经密不可分了,但是自己项目开发中,似乎用到的场景的并不多,难道用pnpm+monorepo
只是为了并行启动项目用吗,显然并不是的
在我的工作中,pnpm+monorepo
主要用于工具/自研库/cli
的开发中,这三者是毫无相干的嘛?并不是的,是密不可分的,monorepo
几乎取代了lerna
进行多包管理,monorepo
可以很好地进行拆包而这三者可以通过monorepo
很好地串联在一起,形成梳理清晰的工作流
我们这里拿varlet
的拆包举例,因为我觉得varlet
在工程化方面做的是很好很清晰的,我也经常来借鉴借鉴大佬们的思路
我们发现,varlet
通过monorepo
拆包,形成了非常清晰的工作流,不论是后期的抽离,还是日常的维护,都是很清晰,舒服的
具体的拆包结构你可以根据自己的项目来定,比如我把一些utils
单独拆出来,单测
我也单独拆出来,达到我自己的预期需求
cli
,也就是我们常说的脚手架
,大部分是用来建设对应的开发模板,中间大致有下面几个阶段
- 命令
commander
插件提供命令注册、参数解析、执行回调
- 交互
inquirer
插件用于命令行的交互(问答)
- 逻辑处理
fs-extra
插件是对nodejs
文件Api
的进一步封装,便于使用kolorist
插件用于输出颜色信息进行友好提示
我们可以生成我们想要的模板,有对应的vue、js、ts、md
等等,可以生成对应的路由
,可以生成对应的单测
,只要是我们想要的,我们每次都需要重复创建,手动添加
的,我们都可以选择去搞一个cli来进行自动化
处理
然后我们大致会达到下面的效果
后面我就不展示了,最后根据提示我们可以自动生成对应的文件模板
同时大家比较关注的还有SDK
的设计,其实大家可能遇到较多的是前端监控/性能的SDK
,本来我想放到后面和监控和优化的时候写的,但是这里都说到了monorepo,我觉得放在这里说也无伤大雅
SDK
的设计我觉得是很值得学习的,我之前设计的思路是webpack
的模式,也就是core
配合plugin
的方式
这里其实会引申出非常重要的一点,也就是webpack
,有些朋友可能就懵了,什么意思,webpack为什么放到了这里,不是应该在打包那里吗
这里就可以纠正一下关于webpack工程化
的误区
webpack打包
是工程化中打包
的一环,而webpack的设计思想
是工程化中工具
以及SDK开发
的一环,而webpack配置和打包分析以及优化
是工程化中优化
的一环
并不是说webpack=工程化,但是并不是说webpack≠工程化,准确地说,webpack贯穿工程化,它并不是单独一两个作用那么简单
这也会体现出面试的一些问题,面试想考察webpack,并不是想单独考察你对比webpack的那几个配置,说白了,那几个配置硬记谁记得住,都是去看文档,但是webpack的设计思想和贯穿工程化的这些知识,才是更重要的
比如,在SDK
开发中,我虽然用的是webpack
的模式,但是我却用rollup
打包,是不是蛮有意思的,哈哈哈哈哈
关于SDK
的设计,我这里也有较为推荐的文章
我开源了一款轻量级前端埋点监控sdk - 掘金 (juejin.cn)
而我们之前在公司里也是采用的这种模式来进行SDK的开发
然后关于SDK的一些指标咱们下面监控和优化的时候再说
单测
单测即单元测试
,其实这个大部分公司內是没有的,因为几乎测试工作都会留给专门的测试工程师来做,前端只专心做业务工作
但是这样会有一些问题,比如测试的时间和开发总是不同步,不知道大家有没有遇到过,到项目上线的最后的那两天,bug突然全被指派了出来,然后开始痛苦地加班
同时我们在进行工具等开发的时候,因为这不归属于业务,所以一般测试工程师是不参与的(当然,如果你们是参与的那更好),而且我们工具对于代码健壮性的要求是很高的,所以我们一般会进行前端方面的测试
那我们通常会进行哪些测试
单元测试
:测试给定函数、类和复用逻辑组件测试
:检测咱们组件的挂载、渲染和交互性端到端的测试
:通过真实网络请求我们应用并检测夸多页面的功能特性
因为我大部分都是用的vue
,所以我们用的vitest
这个框架,相信大家都有听说过,相较于之前的Jest
配置简单,语法几乎相同,文档完善,是个不错的选择
同时,如果你比较关注开源项目的话,你基本会发现,现在基本上开源项目都会有单测的一环,也是PR
的一个硬性要求
一般要求比较高公司或者是开源项目还会对单元测试覆盖率
有一定的要求,这个就是见仁见智了
最后,单测并不是一个硬性的要求,它更多的是用于工具开发等,而在业务上较少去用,对于一个大型的业务项目来说,心智负担过大,所以前端单测现在在公司中属于不太看重的部分(但是我听说,越来越多的公司开始做前端单测了)
CR
CR,即Code Review
(代码审查),我觉得是必不可少的一环,尤其是对于公司新人和实习生来说,它是对代码质量的查验,我们可以发现自己的代码哪里写的不够好,哪里可以进行改善,这对能力的提升是很有帮助的
可以帮助自己建立一个良好的代码习惯,写出更优雅的代码
不同的公司CR
的标准当然是不同的,我拿我经历过的举例
我们CR
间隔是比较长的,一个月一次,因为我们基本上一个月是一个业务周期,基本上一个月能完成预计的项目开发工作,然后最后打包上线前来进行质量审查
审查的点主要包括上面的代码规范
的几点,然后函数的冗杂程度(就是优不优雅)
,如果vue、react的话会看一些hooks
,也就是可复用性
强不强,这个过程是互相看的,如果是实习生一般是导师给看,这一般会涉及到绩效,和转正之类的,其实是比较重要的
像一些文章会写的,什么设计模式
之类的,我觉得一般就是在这里进行体现,虽然我是不怎么用的,可能我写的就不怎么优雅哈哈哈哈
我们一般是下午进行CR,时间是一整个下午左右,基本上时间只多不少,还是比较看重这方面的
打包
其实打包这个大家比较熟悉,我们知道的就有很多,比如vite、webpack
等
其实这么说也不对,我觉得也是大家的一个误区,就是会拿vite
和webapck
来进行打包工具方面的比较
但事实上vite
本质上不是为了打包的,如果真要比较的话也是比较rollup
和webpack
因为后两者才是打包工具,来进行代码的压缩、合并等
操作
而vite
一般会问一些:为什么vite快啊
之类的
也可以问它和webpack的区别,但是拿它和webpack比较我觉得是不妥当的,不知道这也是不是大家的一个误区
我们也会发现,现在的很多业务项目还是采用的webpack
来进行打包,因为它对HTML、CSS、以及很多框架较为熟悉,而且不需要进行单测。
而在我们上面写的,工具、SDk等开发中,我们多数都是逻辑,封装,不涉及上面的那些,而且会进行单测,这时候会选择用rollup
然后关于打包的配置项,其实也没什么好说的,很多都是和优化相关的了,除了优化相关的,我们基本上只关注SourceMap
即可
监控
前端监控
不知道大家具体有没有开发过,但是相信大家大部分是听说过的
这里我做过B端和C端的监控,基本上就是错误监控
、行为监控
和性能监控
错误监控我们比较容易理解,比如网站哪里出错了,我们可以通过监控平台进行上报,定位到哪一行的代码出现了问题(这里就和上面的SourceMap对应上了),然后一般会搭配类似于邮件预警
,比如企业微信
和飞书
等平台,优势就不用多说了
监控平台的选择很多样,例如Sentry
,或者Prometheus
搭配 Grafana
等等,当然,也有很多公司选择自己开发平台,都是可以的
只要设计好SDK
即可
同时性能和行为
我们需要关注一些指标,然后做出直观的可视化报表等
例如
- 首次内容绘制 (First Contentful Paint,FCP)
- 最大内容绘制 (Largest Contentful Paint,LCP)
- 首次输入延迟 (First Input Delay ,FID)
- 交互到绘制延迟(Interaction to Next Paint,INP)
- 累积布局偏移 (Cumulative Layout Shift,CLS)
- 第一字节时间 (Time to First Byte,TTFB)
我们可以通过web-vitals
搭配Performance API
获取标准化的用户体验指标。
还有
- UV访问数(Unique Visitor)
- PV访问来量(Page View)
- 记录用户在页面的停留时间
等等数据需要我们采集
这个时候SDK
显得尤为重要
这就我们需要关注SDK的接入设计
、SDK的运行设计
,然后数据上报的时候数据的过滤
啊,多端
的适配啊,等等
优化
性能优化
貌似是前端这两年的热门话题,最简单的,我们打包的时候可以进行打包分析,比如webpack-bundle-analyzer
,或者你是vite的话就用rollup-plugin-visualizer
然后我们可以直观地看到各个库的打包体积
的占比,然后呢就用CDN
什么的优化,之类的
其实很多优化手段大家都知道,文章也比较多,如果我想具体讲的话,又得开一篇长文,这里我们只说一下一个项目,优化的完整流程是什么样子的
- 性能指标设定
- 性能标准确定
- 收益评估
- 优化手段
- 立项
- 优化实践
当然,也有一些专业的说法,例如RFC
,大家的步骤可能有出入,但是又相似
这里其实我主要想说的是,一个工程化做的好的团队,优化是单独的,很重要的一环,并不是我们开发中随手优化的
性能优化是需要时间和成本的,需要多方地评审和收益评估,如果没有实际指标为目的进行盲目优化,是无法得到其它部门和领导的肯定的
甚至我们每个优化的环节都会进行验证、量化、和评估
而且不光是我们常见的业务场景需要优化,在可视化方面,优化更是让人头疼,比如canvas性能优化
,fps掉帧
一直是大问题,而webgl
更不用说了,比如LOD优化
等等,现在也是面试也越老越爱问了
沉淀
这里的沉淀不只是说个人的沉淀,作为工程化的一环,团队的沉淀是很重要的
比如我们之前会搭建自己公司的知识库,比如直接用wolai
这种的平台搭,也可以自己搞一个
然后定期开技术周会,现在有点记不清了,我记得当时是一周一次,然后需要出对应的文章,就类似于现在的技术文章一样,然后放到内部库里面(每篇文章都算绩效,这很重要!)
然后开发出通用性较强的库和工具也算(都算绩效!)
也可以说是技术交流的一种,把自己了解的新技术分享给大家,因为大家都了解的话也能更好地进行技术评审,没准下一次就用你推荐的这个库了呢
这种制度会让开发的小伙伴更喜欢去做一些提升自身能力的事情,也更能为团队赋能
结尾
其实工程化真的是一个比较灵活的概念,大家不要理解的太过死板
只要做的工作对项目、对团队有长久的有益影响,其实都算是工程化
这篇文章旨在给大家梳理一下自己对工程化的误区,给大家一些方向,并不意在精讲每个环节,因为每环都是很重要和复杂的,需要单独拿出来讲
我个人理解,工程化有利于提升自己的技术广度,也是成为架构的必修课
当然,这里我没有写CICD
的内容,一是在工作中这不是我由我负责的,我做的都是构建等简单工作,二是因为我觉得运维和部署放在工程化中过于牵强
最后,前端工程化
似乎已经成为了一种方向,也是面试中较为加分的点,那么重要性就不言而喻了,希望这篇文章能帮助到大家
近期都比较忙,只能晚上偶尔抽出时间来写文章,所以简短了些
欢迎大家进行讨论,不懂的可以留言,我会尽量回复的
以及写文章的时候有哪部分我一下子没想起来的,我在后面慢慢补充上去,如果需要每部分单独出文章的,大家可以说先出哪一块的,慢慢来~
另外,不做收费项目,不接单,不卖课,没那个实力也不想做,单纯分享,所以理性评论蟹蟹~