内部工具的一次重构,记录下重构过程遇到的坑
背景
内部使用的活动搭建平台,由于历史原因,组件模块开发体验比较差。开发入门门槛以及对整个项目结构的理解成本比较高,同时整体的开发效率比较低。
搭建工具的工作原理比较常规,基于后台的配置文件,在渲染端(ssr)根据配置加载不同的组件,也就意味着组件的载入是一个异步的过程。
现状
活动工具的整体技术栈为:Regular.js + Node.js + SSR。
组件的目录结构:
开发组件跟着组件仓库,如上图中的只有packages内的内容是实际开发者需要关注的内容,其他的内容大部分都是和业务开发无关,开发工具通过Koa静态托管文件,本地起一个代理加载组件文件实现本地开发。
主要存在的问题:
- 组件没办法和管理后台联动
- 组件的容器非最新,线上线下显示不一致
- 组件没有办法和其他组件共同联通,即多组件共同开发
- 整体开发流程特别繁琐:npm link + npm run watch + npm run start。然后依然需要做各种 hack 工作
- 开发工具的规范无法收敛
- 项目结构混乱
- ...
基于以上,最终是想通过借壳开发,保证线上线下无差别,并在开发过程中可以0感知把组件托管到本地。整体的工作思路比较简单,主要在于如何在历史深坑中,一个个去“补填”
重构后的架构
统一代理服务
本地启动一个代理服务,作为一个全局请求的统一入口,负责分发各个请求。
根据不同的类型,请求到不同的接口下。
本地组件静态服务
对于本地的组件,依赖webpack watch 打包出静态文件并监听,如有多个,则启动多个webpack watch进程;同时启动一个静态资源服务(port:8061)进行托管,
为什么选择webpack watch?
- 历史组件的构建方式都是webpack watch 可以比较好的兼容老的版本。
- 方便内容托管在同一端口下,方便多组件共同启动。
hot live 这里依赖webpack-plugin-serve
启动服务后,访问127.0.0.1:8001/activity
登录依赖第三方登录,活动工具后台的的服务端是一个node 服务,页面也是由服务端直出,登录的状态是依赖node-session通过第三方登录进行node登录。管理后台不是一个前后分离页面,访问该路由,直接重定向到管理后台,直出document,但是当前域名下并没有登录态。
而我们这里需要一个本地第三方登录。如何解决呢?
这里通过前端静态服务托管一个登陆服务页面(admin-login),通过第三方登录写入127.0.0.1 登录cookie,写入cookie后,重定向到node-server,通过重定向补齐session状态,完成 node 登录。
这里会有一个问题,即 node-server 未登录以及前端模拟登录完成重定向到node-server,都是未登录并返回302,那如何判断何时触发本地登录流程呢?
这里通过判断返回的 status code 为302,并重定向3次作为触发本地流程的起始条件
管理后台组件连接到本地开发环境
上文已经提到,本地组件已经被托管在8061端口下,那如何区分把本地的开发组件连接到真实环境中,组件的加载是一个异步过程,就是会单独通过 script 标签 加载组件的js/css。
在启动的时候,通过选择的开发组件,生成一个配置文件。通过此配置文件,对所有的组件资源进行筛选,如果是开发组件,则将资源重新链接到8061端口下的静态地址。这里并没有区分版本号,即只要本地有代理,则直接会覆盖线上的资源,从而达到本地调试的目的。
同理,对于启动开发的组件这里也需要动态插入到module list中,从而保证本地模块可以在页面编辑的时候被正确检索到。
用户端的组件连接到本地开发环境
活动工具搭建出的页面是通过ssr输出到用户。除了基本的容器及热区等,是通过ssr直出,而组件本身的内容其实是通过csr重新生成的。而组件的相关信息是通过直接注入到html中
<script> var __moduleJsUrl__ = ["/tms3/posterGenerate/posterGenerate/1.0.3/index.min.js"] var __moduleCssUrl__ = ["/tms3/posterGenerate/posterGenerate/1.0.3/index.min.css"] </script>
容器的js会根据这个全局变量动态注入组件js。
那这里就是直接暴力拦截document内容,把其中的内容里追加本地调试的组件。
至此基本调试流程已完成。
新的组件项目的结构
项目中的包含的内容和开发高度相关,其他均收敛到一个脚手架中
// package.json { "name": "xxx", "moduleType": "xxx", "title": "xxx", "version": "1.0.0", "icon": "th-large", "description": "", "base": "react", "tmsVersion": "3.0", "main": "src/main.js", "scripts": { "init": "tms3-cli init", "start": "tms3-cli watch", "build": "tms3-cli buildAll", }, "keywords": [ "activity", "tms3.0" ], "devDependencies": { "@music/tms3-cli": "x.x.x" }, "dependencies": { } }
对于组件本身的脚手架也有调整,主要是项目组织方式以及配置的优化,这里先跳过。
主要功能介绍:
tms3-cli init: 通过交互的方式生成组件的脚手架,组件的脚手架是包含完整的依赖,这里生成的时候回根据最外层的依赖,动态删除组件的依赖,一定程度提高开发及构建速度,防止包的冗余。毕竟一个项目的组件的数量可能达到几十个。
tms3-cli start:一键启动开发,启动各个服务
tms3-cli buildAll: 构建所有组件,这里增加了多进程构建,对于多组件的项目提升至少200%,
发布平台, process.NODE_ENV 默认为production,装依赖主要特别的把devDepencies装全。
tms3-cli us: 一键升级老的脚手架项目。
q
其他
- 新版本检查
- 组件脚手架及部分方法热更,在watch及init方法的前后会注入。用于在一些极端的情况做到及时触达,比如重要的通知,或者一些变更等。
- 试水了wasm在node的运行,可以保存一些非明文的信息,对于这部分感兴趣的可以参考链接
- 统计项目覆盖服务 based on gitlab api。
最后
本次重构是基于“历史包袱”,在不影响现有业务的开发前提下一次比较平滑的升级。值得肯定的是,没有耽误业务方的迭代,对于开发及构建有非常大的提升。