乐趣区

关于javascript:Worktile-前端工程化之路

前端过来十年可所谓是百花齐放、百鸟争鸣,技术也是突飞猛进,前端社区曾经被打上 娱乐圈 学不动了 的标签,也就是在这十年左右工夫,前端工程化慢慢的进入了大家的视线,越来越多的公司开始器重前端工程化,那么什么是前端工程化能够参考不久之前我在知乎的一个答复 什么是前端工程,近两年前端工程化根本趋于稳定,每个公司都积淀了本人的一套工程化实际办法和工具,那么 这篇文章次要分享一下 Worktile 从 2013 年至 2020 年的前端工程化之路,介绍一下一个初创公司在过来 8 年的前端工程化演变的过程,一张简略的图回顾一下过来 8 年:

2013 Worktile 诞生

工夫回到 2013 年,那年我从一个服务端工程师刚开始接触前端,第一次据说 Hash 路由:浏览器 URL 变动后整个页面竟然没有刷新,那年同时也是 Worktile 诞生的那一年,对于一个团队合作平台 SaaS 产品,咱们次要面临的前端工程化问题就是:前端框架选型。

对于过后来说可抉择的框架并不多,Vue,React 还没有呈现,最终咱们抉择了 Angular.js 作为前端开发框架,次要起因就是:Angular.js 适宜做 Web App 体验的 SPA 单页利用,反对数据双向绑定,数据驱动开发,防止手动操作 Dom。

抉择了 AngularJS 后,我从开发、构建、部署三方面论述一下过后的工程化程度。

  • 开发:第三方依赖包手动拷贝和保护、目录构造依照框架性能划分、所有状态都存储在 $rootScope;
  • 构建:通过 uglify-js2 手写了一个 Node 脚本压缩合并,没有应用构建工具;
  • 部署:我记得印象特地粗浅的就是部署,每次发版 CEO 须要通过 Beyond Compare 一个文件一个文件比照,而后咱们一起看一下批改内容,决定是否同步更新到服务器,而后重启服务。

当初回过头看 2013 年,感觉过后的前端工程化根本处于原始社会,那年的 CEO 和 CTO 也都还是一个开发工程师,一共就 4 集体,一个前端还负责 UI 设计,这根本就是一个刚成立的守业公司的状态,产品能疾速跑起来就行,要啥工程化。

2014-2015 年,LessChat 诞生

工夫到 2014-2015 年,因为要做一款 Slack 的中国版产品 LessChat(起初基于 Lesschat 的根底之上新增了工作、网盘、日历模块,也就是当初的 Worktile),因为是一个新产品,基于过来的教训必定须要重新考虑整个前端的架构设计,咱们同样从开发、构建、部署三方面论述一下过后的工程化:

  • 开发:开始引入包管理工具 Bower,依照模块划分目录构造,模块根本意味着一个畛域,防止一个组件一个性能扩散在不同的文件夹,同时前端引入数据层 Service 作为治理状态,不再是所有的状态存在 $rootScope 中了,其余的就是引入了一些 Lint 工具;
  • 构建:先后引入了 Grunt,Gulp 构建工具;
  • 部署:应用中转折 Shell 脚本一键部署,不再应用 Beyond Compare 比照上传。

2016 Webpack + 模块化

2016 年,最大变动就是构建工具和包管理工具的转变,从 Gulp 切换到 Webpack,从 Bower 切换到 npm,其实工具的转变实质的起因就是:模块化,前端开始器重模块化开发了。

那么 Webpack 无疑是前端开启模块化的转折点,同时 Webpack 反对 CommonJS 标准,这样使得前端能够应用 NPM 的生态,Bower 天然就被淘汰了。

在前端引入模块化之前,为了防止命名抵触,个别会采纳命名空间和自执行函数的办法,引入模块化后命名抵触的问题就随之而解,再也不必本人包装一个自执行函数了,那么除了解决命名抵触外,引入模块化带来的价值远不止于此。

  • 便于依赖治理:再也不必手动保护 Script 引入的程序问题
  • 利于性能优化:能够利于 Webpack 打包工具实现合并,按需加载,更细粒度的模块划分搭配动静加载
  • 进步可维护性:依照模块划分,每个文件繁多职责,组织构造清晰正当,可维护性也就大大提高
  • 利于代码复用:代码复用不是模块化的最终目标,反而是附带的价值

应用模块化和组件化最重要的意义是在于分治(分而治之),能够说中大型前端我的项目终于变成可保护起来,这也是前端工程化的意义所在,如果前端不是变得越来越重要,越来越重,也不会有什么前端工程化。

因为咱们采纳的是 Angular.js 框架,基本上能够说是不反对模块化,能够通过下图感受一下 Angular.js 的模块化。

这里顺便介绍一下模块化的倒退历程:

随同着 2009 年 Node.js 的诞生,CommonJS 进入了大家的视线,CommonJS 是 JavaScript 的动态模块化标准,适宜 Node.js 不适宜浏览器环境,前端资源除了 JS 外还包含 CSS,图片等,同时 CommonJS 是同步阻塞式加载,无奈实现按需异步加载。为了让浏览器环境也能够应用模块化,起初诞生 AMD/CMD 标准。不论是 CommonJS 还是 AMD/CMD,他们都是在语言标准缺失时代背景下的产物,利用场景繁多,模块无奈跨环境运行,构建工具不对立,不同标准的模块无奈混合应用,模块复用性不高。直到 2015 年 ES6 Module 一统天下,前端模块化终于趋于稳定。

2017 前后端拆散

2017 年,Worktile 前端工程化最次要做了以下两件事:

  • 全站模块化(2016 年引入模块化后历史模块迁徙须要工夫,根本一年的工夫陆陆续续全副迁徙结束)
  • 前后端仓储拆散(2017 年之前,Worktile 前后端都是在一个仓储的,尽管是 SPA 单页利用,HTML 是服务端渲染)

说到前后端拆散,这里简略介绍一下前后端拆散的两种模式

全动态我的项目

对于前端是全动态的我的项目,部署后 HTML 文件是不能强制缓存的,Nginx 须要配置 try_files 指向到 index.html。

HTML 模板是服务端渲染

对于服务端渲染 HTML 模板的模式下又有两种子模式:

  • 第一就是 HTML 模板是由服务端团队负责,这种模式工程化须要解决前端构建后的资源如何告知服务端更新资源的问题;
  • 第二种子模式是大前端,前端团队应用 Node.js 实现渲染 HTML 模板,甚至和前端我的项目在一个仓储中保护。

2018 前端工程化元年

2018 年,我认为是 Worktile 开启前端工程化的元年,2018 年之前咱们始终在应用 Angular.js,尽管过来也始终在做架构调整,引入了模块化等等,然而不可否认 Angular.js 是曾经被淘汰的前端框架,所以 过后大胆的降级到了 Angular,次要思考有以下几个起因:

  • 2018 年,Worktile 产品打算做 8.0,一个高度配置化的项目管理模块,复杂度急剧回升
  • 咱们想开始搭建本人的组件库,基于 Angular.js 感觉如同没有太多的激情和能源
  • 持续应用 Angular.js 也会面临着招人艰难的问题,人才培养也是如此
  • Angular 框架正式公布后也逐步趋于稳定,能够投入生产应用
  • 至于为什么没有抉择 Vue 和 React,次要咱们比拟合乎 Angular 的哲学,大而全解决咱们所有的痛点,人少,没有尽力折腾

基于以上几个起因,我开始通读了一遍 Angular 官网文档,初步跑通了 Angular + Angular.js 混合计划,而后做了一次技术分享,大家也比拟有激情,就间接引入 Angular,同时也因为 Angular 一起引入了 TypeScript 和 RxJS。

除了降级 Angular 外,2018 年咱们还做了以下几个重大的工程化改良:

  1. 搭建了外部的组件库:ngx-tethys(对于过后咱们团队规模和业务压力来说是不敢设想一个前后端加一起 10 人左右的开发团队竟然搭建了外部的组件库);
  2. LESS 迁徙 SASS,bootstrap3 降级到了 bootstrap4(款式的天坑也是须要填的,好在这所有都踩过去了);
  3. 应用 RxJS 作为状态治理,封装了适宜咱们业务的轻量级状态治理类库,更多细节能够查看 Angular 真的须要状态治理么?

降级 Angular 混合利用也会遇到了一些问题:

  • 第一就是性能问题,Angular 的 Zone.js 集成到遗留零碎中会大概率呈现性能问题,须要把所有影响性能的绑定事件都改成 runOutsideAngular​;
  • Angular.js 和 Angular 路由还是会有一些抵触,同步路由等问题,须要不停的踩坑尝试,有可能写了一些当初永远看不懂的代码,Angular.js 应用的是 ui-router,并不是官网的路由;
  • 尽管 Angular.js 和 Angular 之间的服务和组件是相互能够调用的,弹出模态框的机制是不同的,Angular.js 应用的是 ui-bootstrap,Angular 应用的是 CDK,所以层级的抵触问题也比拟辣手,fork bootstrap 的组件库批改源代码解决模态框抵触问题。

回顾 2018 年,因为技术升级和新业务的确带来了很多压力,咱们很多的技术选型是减轻了大家的累赘,然而这所有是十分的值得,因为技术升级给整个前端团队带来了微小的能源和能力的晋升,很多小伙伴在这一年能够熟练掌握 TypeScript 了,也具备了独立搭建组件的能力,可能过来想都不敢想,这么简单零碎的降级和迁徙都走过去了,还有什么迈不过来的呢?(我永远都记得前端刚开始应用 TS 的各种 any)

2019 PingCode 诞生

2019 年,咱们开始做研发管理工具(2020 年 10 月独立为 PingCode),这又是一个新的跨时代的产品,之前我说过技术的改革往往和产品非亲非故,在 Worktile 这 8 年,根本经验了四次大的产品变动,前端工程化根本也随同着这四次产品变动而变动,对于这一年,开发、构建、部署几个环节都做了冲破的变动。

开发

对于开发,除了持续抉择 Angular 框架外,最重要的是引入了 微前端,之前我也分享过: 应用 Angular 打造微前端架构的 ToB 企业级利用

  • 自研了 ngx-planet 微前端框架,所有子产品独立仓储,独立部署
  • 因为独立仓储,所以须要搭建业务组件库,抽取业务通用组件
  • 开始器重单元测试,根底库强制编写单元测试,过来的组件库开始补充测试
  • 引入了 wt-cronus 工具一键克隆、更新、装置、启动多个利用,解决多个仓储难以治理的问题
  • 前端是全动态的 SPA 单页利用

此时你必定会问:为什么不采纳 Monorepo?最初我会具体介绍一下过后为什么采纳微前端吧。

构建

2019 年前后端开始引入了 jenkins 做继续集成,因为前端采纳了微前端,所以构建采纳了基于 Angular CLI 的 angular-builders 扩大构建器,即能应用 Angular CLI 带来的便捷,又可灵便的扩大 Webpack 的配置适配微前端的框架。

部署

和构建一样,2019 年前后端应用 jenkins 做继续部署,所有服务都采纳 Docker 容器部署,同时采纳 kubernetes 进行容器的部署、扩大和治理,全面实现了自动化运维。

标准和流程

除了开发、构建和部署几个方面的晋升外,2019 年开始引入了《Commit Message 提交标准》、《分支治理标准》(相似 GitFlow)和《Code Review》。

  • 引入 Commit Message 标准,对于类库的我的项目来说能够主动生成 Changelog,对于利用来说能够更好的追踪 Git 提交记录,同时和 PingCode Agile 的用户故事进行双向关联;
  • 分支治理配合主动部署和发版流程,让版本治理和主动部署更加标准和流程化;
  • 起初引入 Code Review 比拟担心的问题就是:是否会减轻大家的工作量,通过实际效果来看,Code Review 带来的利远远大于弊,不仅仅每个人的代码品质晋升了,浏览和了解他人代码的能力也失去了晋升。

为什么抉择微前端?

任何技术选型外围的起因还是取决于业务需要,如果能够通过不引入微前端也能解决公司遇到的工程问题,那么最好就不要引入微前端,那么咱们过后为什么没有采纳 Monorepo 而采纳微前端架构呢,次要起因如下:

  • 兼容遗留零碎:刚开始做 PingCode 的时候是打算和 Worktile 集成在一起的,Worktile 是一个宏大的 Angular + Angular.js 混合利用,一是编译打包速度曾经很慢,二是很多工程的货色不标准,批改起来很麻烦,采纳新的架构设计反而会更简略(起初产品上线之前最终抉择了独立,并没有集成 Worktile);
  • 多团队多子产品:起初就蕴含了 4 个子产品,每个子产品都是独立的 Scrum 团队负责,而且预计未来可能会有更多的团队做更多的子产品,截止到目前为止蕴含内测和下线的子产品共 8 款,不论是团队治理还是仓储治理必定是独立离开比拟现实;
  • 利用市场:在产品布局初期,咱们指标就是想要打造相似 jira 一样丰盛的利用市场,等于除了加载官网的子产品外还会加载利用市场的内嵌利用,甚至当前还会有第三方开发内嵌利用,目前『待办』和『甘特图』两款内嵌利用就是咱们外部做的利用。

当然抉择微前端后尽管解决了很多通电,但同时也带来了一系列的工程问题:

  • 独立仓储后必须要构建业务组件库
  • 业务组件库越来越宏大,打包、公布速度越来越慢?
  • 不反对真正意义上的独立开发,本地开发要启动 Portal 等多个服务
  • 子利用本地开发须要手动刷新页面,不反对 LiveReload 和 HMR
  • 整个零碎太简单,理解整体架构变得更加的艰难
  • 没有款式隔离,子产品部署还须要部署 Portal

遇到问题并不可怕,一个一个的解决即可,如果当初抉择 Monorepo 我置信也会遇到其余的工程问题。

2020 规范化 & 流程化

随同着微前端带来的一些列工程问题,咱们进入了 2020 年,2020 年次要就是解决这一系列问题:

  • 子产品真正意义上的独立开发,不须要启动 Portal 等多个服务
  • 真正独立开发后的 LiveReload 和 HMR 也逐步反对
  • 款式隔离计划的确定和落地,每个子产品齐全独立部署
  • 外部的 devkit 工具集欠缺,通过 wpm release​ 和 wpm publish​ 简化发版流程

组件文档

过来两年,咱们打造了组件库和业务组件库,那么组件库的文档还是比拟毛糙,2020 年另一个重要的工作就是欠缺文档,为了欠缺文档开发了一款文档生成工具 Docgeni – Angular 开箱即用的组件库文档生成工具(后续会正式开源进来),基于 Docgeni 咱们迁徙并重构了组件库和业务组件库的文档。

测试覆盖率

组件库和业务组件库的测试覆盖率晋升到了 70%,因为过来的债权太多了,咱们对于服务端的测试覆盖率要求始终比前端高,服务端一般子产品的单元测试覆盖率根本都 80% 以上,补充测试是一个坚持不懈的工程化问题,同时也定义了公司的测试覆盖率指标。

开发标准 & 流程制度

2020 年除了上述的以外,我感觉是 Worktile 开始走向规范化、流程化的一年,WTC(技术委员会)公布了 16 个开发标准和 16 个流程制度。

2021 以及将来

以上是 Worktile 过来 8 年的工程化之路,作为一个初创公司,其实很不容易,因为没有太多的资源投入,咱们始终保障产品高速迭代的同时欠缺前端的工程化,不论组件库还是开发工具,都是所有业务团队前端成员共同努力的后果,可能横向和大厂比照,咱们还很落后,然而对于前端团队规模 20 人 还不到的企业来说曾经很不容易了。

2021 年才刚刚开始,咱们也将会持续把前端工程做的更好,一步一步欠缺本人,2021 年以及未来我认为次要从 求实 平台化 两方面继续发力。

对于 求实:过来咱们曾经构建了组件库、微前端、Docgeni、Devkit 等基础设施,那么将来须要继续欠缺,测试和文档的继续改良,其二就是会引入更多的自动化工具简化咱们的工作流程,最初就是开源、回馈社区,过来咱们开源了 微前端 ngx-planet,之后会把咱们更多对于前端的工具、类库开源进来,回馈社区,包含我写的这篇博客,也是心愿让更多的人理解 Worktile 的前端工程化之路,或者对于同样是初创公司的你一些参考和帮忙。

平台化:在求实的根底上,如果精力和资源容许会引入一些平台化的工具,比方:前端监控平台、灰度公布零碎等等。

写在最初

我自己始终见证着 Worktile 前端工程化一步步走到当初,把咱们的心路历程过分享进来须要勇气,我没有去过大厂,也不是很分明前端工程化做的特地优良的企业到底是什么一个状态,如果你对此有什么想法欢送大家一起交换(特地是国内应用 Angular 框架的企业)。最初打一个广告:咱们正在做一款比 Jira 更好用的研发管理工具 PingCode,欢送大家注册理解!

智能化研发管理工具 PingCode- 官网

退出移动版