在消费者端,为了方便各条业务线接入,我们通常以组件的方式提供功能,但是组件的发布必须依赖于页面的发布,页面发布又通常需要业务方统一操作,比较影响组件的迭代速度。
经过一段时间的探索和开发,我们实现了一种可以让组件独立发布的异步方案,具备以下特点:
下面我介绍一下我们的方案。
一句话概括:将组件独立打包成 UMD 格式的 js 文件,页面加载时通过动态生成 script 插入该 js,插入完成后渲染组件。
组件单独打包是异步组件实现的基础,动态获取 js 能实时地获取最新版本,再结合组件动态切换可以实现组件的升降级。
异步组件方案核心功能通过消费者端组件、Node 端插件和打包服务三部分来实现:
使用异步组件的流程:
具体思路如下图所示:
首先我们需要将原本ESM 或者 CJS 的组件打包成 UMD 规范或者 IIFE 的形式。
打包配置可以根据每个组件的内容和使用方法单独配置,不需要修改代码,所以组件依然可以通过 NPM 的方式引入。
打包完成后,为了加快文件的下载速度,通过脚本将文件上传到 cdn 服务器,然后将返回的 cdn 地址同步到配置中心。这样我们就完成了组件打包层面的解耦,将组件打包流程从项目打包中独立出来。
这里有一个优化点,可以把一些公共的依赖排除在外,使用时在项目中配置组件的外部依赖,不过需要注意该组件依赖的版本和项目中依赖的版本是否兼容。
Node 端收到页面请求后,获取当前组件在配置中心包含灰度切流比例和A/B版本信息的配置内容,A/B版本的使用会在组件动态切换中详细介绍。
每次请求都会获取最新的异步组件配置,所以配置更新时能够第一时间在线上生效,异步组件的发布和秒级回滚都依赖这个特性。这个功能我们通过插件的方式来实现,保证业务代码的足够精简、稳定,使用也方便。
Apollo 使用分布式部署,可用性高且能实时更新配置,同时也可以在开发、测试、生产等环境分别部署运行,对开发很友好。
为了进一步提高异步组件的加载速度、减少请求次数和耗时,我们将异步组件配置在node层返回 html 模版的时候注入。整个流程分为 4 步:
线上的稳定性非常重要,当异步组件地址获取异常、加载异常、没有命中切流或其他异常情况发生时,vue-components-injector 会立刻根据配置策略动态切换到其他版本或使用 NPM 引入的原组件,保证异步组件在极端情况下的可用性。
组件升级也是经常出现问题的地方,我们可以通过配置A/B版本信息并结合百分比切流来实现组件版本稳定升级。
例如 我们将 A 版本设置为当前版本的 js 地址,B版本配置为将要发布的新版本,将流量通过修改灰度比例逐步切换到B版本,如果遇到异常情况,可以通过修改组件配置立刻切回A版本。
最近我们陆续将交易下单页中的储值卡和收银台的引入方式替换为异步组件加载,得益于我们比较充分的准备,替换过程比较顺利,上线之后也比较稳定,达到了预期的目标。
后续我们会简化异步组件的接入流程,扩大接入范围,优化有赞消费者端用户体验。
本文转载自公众号有赞coder(ID:youzan_coder)。
原文链接:
领取专属 10元无门槛券
私享最新 技术干货