从业务组件库看前端工程化

这半年多大部分精力都是在做业务组件库,而在业务组件库的开发维护中出我另一个主要做的事就是组件库(或者说是物料资产)的全套工程化流程。

本文不是一篇教学文章,仅是对近半年一部分工作的流水账式的总结,也作为自己的一份备忘录,并且因为是公司内部资产很多地方不能贴源码和截图,如果有对其中内容感兴趣的欢迎一起讨论。

浅谈前端工程化

在我看来,前端工程化就是指把平时工作流程中的一部分繁琐重复的工作以工具的形式沉淀出来,从而减少开发同学机械化的重复劳动。这里的工具不限于本地项目脚本、云端服务等。例如:我们通过 CRA 去初始化工程项目、通过 Webpack / Vite 对项目进行打包构建、通过云端服务对前端项目进行上线等等。

从我个人的经验而言,一切开发中涉及到的简单的重复机械性劳动,都能或多或少的通过工程化能力得到明显改善。

前端工程化就和性能优化一样旁系众多,而本文的主要切入点在于前端工程中的自动化,利用工程自动化的能力渗透物料体系的初始化->开发->构建->上线全部生命周期,拒绝一切不高效。

从生命周期看工程化全流程

111.png

初始化阶段

对于初始化阶段,物料侧提供了组件/区块的初始化模版以方便组件/区块的快速初始化。

开发阶段

作为物料体系的展示站点,包含了组件、区块、解决方案、工具集合等多维度的前端资产,因此采用 MutiRepo 架构,并完全脱离传统的 npm link 包开发模式。

  • 在组件侧 & 物料侧,开发脚本启动后,实时监听源码的变更并同步到站点的缓存目录。
  • 在站点侧,增加 .dev 目录作为本地开发的缓存目录,在 dev 模式下将组件库 alias 到 .dev 开发目录下。并在 Vite 的加持下,持续提升开发体验。
    • 冷启动阶段,本地开发脚本预检测 .dev 目录合法性,如不合法则全量拷贝 node_modules 下组件源码作为临时缓存文件。
    • 热更新阶段,devServer 监听 .dev 目录文件的变更实时热更新。

更多本地开发相关可查看我之前写的文章:用 Vite 加速你的生产力

构建阶段

物料侧构建阶段只是构建生成 ESM 包和 ES5 的包,这里主要说下站点侧构建时做的事情。

222.png

生成文档

由于组件库完全是通过 ts + 符合 jsdoc 规范的注释开发的,因此在文档这一步我们通过脚本:

  • 扫描全部组件目录;
  • 通过 typedoc 解析组件类型声明以及注释生成文档 AST JSON;

之后站点在运行时解析文档 AST JSON 并生成文档。

生成依赖关系

我们的展示站点又一个功能是展示当前业务组件所依赖的原子组件并生成依赖关系图,和生成文档的逻辑类似,我们会通过脚本扫描业务组件目录分析业务组件的 AST 生成依赖关系 JSON,站点会在运行时动态加载 JSON 展示依赖桑吉图。

生成组件基本信息

组件的元数据已经寸在组件源码里存在了,那在站点侧就不需要二次维护了,因此,在生成依赖关系的同时,我们通过 AST 解析了组件内的元数据,生成了组件基础信息 JSON。站点会在运行时动态加载 JSON 展示组件名、组件设计师、组件描述、组件设计稿等信息。

同步区块代码

之前的文章从业务组件库看前端物料生态分享过,我们的区块以源码的形式存储,那么在构建时实时拉取最新的源码就是刚需,因此,我们通过工程化脚本实现了如下功能:

  • 对于区块:

    • 读取区块 Container 目录;
    • 分析 Container 下区块变体依赖;
    • 通过工具拉取主 / 子区块;
    • 站点运行时加载代码;
  • 对于解决方案:

    • 读取解决方案下 material.json 文件获取解决方案依赖;
    • 通过工具拉取主 / 子区块;
    • 站点运行时加载代码;

上传 Demo

我们业务组件库的 Demo 预览实现方式不同于其他组件库,其他组件库是在开发时通过在 markdown 上编写 Demo,编译时将 markdown 解析成 HTML。我们的业务组件库 Demo 会在站点测以 tsx 源码形式存储,构建时上传到 CDN 上,运行时加载 CDN 源码资源实时预览。

发布阶段

对于从物料到站点的发布,我们有严格的链式发布流程:

333.png

首先对于组件和区块,我们通过自动化发布工具 materials-tools-release 自动化发布 NPM 和 CDN,减少了代码合并、分支检查、版本检测、自动化脚本、发布等步骤的成本并降低了出错的风险。

以前的发布(以组件库为例):

555.png

  • 这是一种规范,没啥好说的;
  • 这一步你可能忘了;
  • 这一步你也可能忘了;
  • 这一步你也也可能忘了;
  • 这一步你也也也可能忘了;
  • 这一步可能是你忘的最多的一步,但是可以通过 prepublish 勾子弥补;
  • 这一步可能是你唯一会执行的;
  • 我觉得你可能都不知道这是个啥;

现在的发布:

777.png

步骤少了,出错就少了。

最后是站点部署。

工具沉淀

在此过程中,我们沉淀了一套服务于通用组件库场景的工具集合。

materials-tools-ast

基于 babel 做了二次封装,可以方便的获取文件的导入导出等能力。分析组件衍生关系

materials-tools-cli

material-tools-cli 主要提供了两部分能力:物料拉取内核 + 物料拉取 cli 工具。其中内核服务于 cli 工具和 vscode 插件主要做了以下这些:

  • 识别物料是否存在,识别当前目录是否存在同名物料名;
  • 根据物料名从 CDN 拉取物料;
  • 根据拉取下的物料依赖合并依赖并提示;

materials-tools-utils

对工程化脚本开发过程中常用工具函数做了封装:

  • file.ts:文件操作;
  • log.ts:日志输出;
  • command.ts:命令行执行操作;

materials-tools-release

自动化发布工具,减少了代码合并、分支坚持、版本检测、自动化脚本、发布等步骤的成本并降低了出错的风险。

工具集的自动化发布

工具集采用基于 lerna 的 MonoRepo 架构,但是 lerna 并不满足我们的一些诉求(例如,我们有很多统一的自定义 npm 勾子的诉求),因此我们在 lerna 的基础上做了二次封装:

  • 通过 lerna changed 获取已更新带发布的包版本信息;
  • 通过 lerna version 更新待发布的包版本;
  • 根据配置文件排序,例如,a 依赖 b,b 依赖 c,那么排序后就是 c -> b -> a;
  • 根据排序后的 list 依次执行 按自定义 hooks 执行顺序依次执行;
  • 发布;

猜你喜欢

转载自juejin.im/post/7070022440079851527