任何一个前端组件库,无论是业界知名的tdesign、ant-design还是element-ui,都有自己系列化的图标。经过观察,发现这些图标在组件库发布时基本稳定,很少有调整,所以可以一直存放在组件库的git仓库中。但是我们现在业务使用的组件库是根据业务需要逐步搭建的,里面的图标也是不断更新的。一直以来,我们也是采用将图标放入库中,与组件库一起维护的方式。对于设计团队添加的每一个图标,都需要委托组件库的开发者将图标入库、提交、发布版本,并在业务端更新组件库的版本。这种做法带来的问题是操作繁琐,效率低下,而且还会导致组件库的版本号暴涨。CHANGELOG几乎都是“加个图标”,不利于整体维护。为了解决这个问题,一种思路是将组件库和图标库进行解耦,分别维护,使用时合并。tdesign是这样做的:https://tdesign.tencent.com/v...不过这样还是有点麻烦,连图标的npm库也有维护成本,还需要自己设计导出icon,添加到git仓库并Release;业务方也要及时更新图标库。有没有办法保存上面提到的步骤?让我们扩展一下我们是如何做到的。整体的解决思路也遵循“解耦”的理念,让组件库和图标库相互独立。首先我们来分析一下我们的业务和icon的关系。1、我们业务中图标都是SVG格式,可以放在CDN上。2、这些图标有不同的分类,如“基本图标”、“音视频图标”等。3、在实际跑业务中,基本都会用到这些图标。之前都是采用fullimport的方式,所以可以不考虑tree-shaking。基于以上三个背景关系,我们的图标就可以按照分类一个一个的上传到CDN了。如上图所示,将“媒体”类型的图标聚集在一起,以JSON的形式存储在CDN中。其他类型的图标也以同样的方式存储。我们的组件库是基于Vue开发的,图标组件通过传入名称显示特定的图标。组件内部维护了一个manifest对象,里面存放了所有的图标资源。这些图标资源是通过动态导入从JSON文件引入的:asyncbeforeCreate(){for(constcateoficonCates){const{default:icons}=awaitimport(`./manifest/${cate}.manifest.json`);this.manifest={...this.manifest,...icons};}this.getSvgIcon();}可以看到这里导入的json文件是存放在组件库本地的,貌似没办法克服“图标更新了,组件库也要更新”的问题同时更新”。这是真的吗?我们先把这个问题搁置一旁,换个角度看看组件库封装后的样子。我们的组件库是基于Vite开发的,它的封装也是基于它的。组件库构建完成后导出到dist目录。我们看一下它包含的内容:可以看到代码中通过动态imoprt输入的json文件打包后变成了对应的js文件。我们打开其中一个:原来打包工具只是简单的将一个JSON文件转换成一个导出对象的js文件。由于我们的组件库也是以npm包的形式提供给业务方的,也就是说,当业务方使用npminstall安装组件库时,实际上会触发组件库中的一系列npmscript生命周期钩子。npmscriptlifehook的内容可以查看官方文档https://docs.npmjs.com/cli/v8...,这里摘录一段我们需要用到的:在业务端执行npminstall即可安装组件库,会触发组件库中的postinstallhook。我们可以在这个hook中拉取最新的iconjson文件,编译成js放到组件库的正确目录下。通过这种方式,业务方在安装组件库时,已经完成了最新图标库的拉取。图标管理系统以往新添加的图标需要正确放置在组件仓库的某个目录下,引用的文件和文档的内容需要手动改写才能合并到主干发布。过程非常繁琐。基于最新的想法,我们希望图标可以完全由设计团队维护,无论是添加、修改还是删除,都不需要与组件库有任何交集。基于这个需求,我花了两天时间搭建了一个图标维护系统:设计类的同学可以通过拖拽的方式完成图标的上传,通过几个选项提交图标。这是一个非常有趣的内容。设计师通过Figma倒出SVG图标,这些图标默认具有硬编码的宽度、高度和颜色。如果直接用在业务端,就会出现问题。因此,在提交图标之前,必须对其进行改造,删除或重写硬编码的属性。如图所示,SVG图标写成宽高12px,颜色为黑色。这些属性应该被删除。为了高效优雅的处理,我先把这个图标的XML文件解析成一个HAST(HypertextAbstractSyntaxTree),基于这个HAST修改,再还原成XML。具体代码如下:上传图标的问题解决最后这个系统还可以用来删除某些图标:组件库postinstallhook组件库触发脚本拉取最新图标库JSON文件的逻辑通过postinstallhook,并将json文件编译成js文件:在npmscriptpostinstall命令中添加一行:这样,在业务端执行npminstall时,就可以拉取最新的图标库资源了。对于组件库的文档,这些图标的json文件也可以实时显示:这个方案说到底不是很强大,但是对于我们的应用场景来说还是很方便的。虽然基于业务考虑不需要考虑tree-shaking,但是“我可以用,你不行”。如果可以,我还是希望支持tree-shaking,我需要花点时间研究一下怎么破解。另外,可能存在线上修改图标影响线下业务的问题。这个问题比较容易解决。您只需要从文档中删除图标,而不是从CDN中删除图标。但我们现在不这样做,主要是因为维护人员在我们的团队中。有问题在群里喊就行了,但是这个方案要推广,还是要做好这些兼容的方案。写完了,点个赞吧~