随着研发代码的增多, 工程日益复杂,代码复用和版本管理显得格外的繁琐,版本升级没有日志,相互依赖的包需要手动管理版本,以往的组件库独立开发的方式并没有很好的区分组件和组件之间的关系,往往只需要一种类型的组件,例如图表,但还是不得不安装一整个组件库,并没有很好的对组件进行区分,如哪些是图表组件,哪些是功能组件,哪些是业务组件等,造成组件库越来越大,编译打包效率降低,每次一个小改动就不得不直接发布一整个包预览效果,且无法支持本地调试等以下相关痛点。
- 组件耦合严重,组件代码量大
- 业务开发分工不明确,业务开发人员要关心非业务的代码
- 编译慢,效率低
- 无法对应用做增量编译&增量部署
- 相关包基础依赖可能会重复打包,如: lodash,moment...
- 管理、调试、追踪 bug 困难
- 不同项目之间 node、node-sass、webpack 等基础依赖版本不统一,切换增加心智负担。
- 不同项目可能存在技术栈不统一,如:状态管理,less,sass
- 分支管理混乱
- 多包多项目之间依赖关系复杂
- 第三方依赖库版本可能不一致
- 占用总空间大
- 不利于团队协作
- 无法针对主应用统一跑测试用例,发布时很难避免一些基本的错误发生
- 需要频繁切换项目
- 搭建独立的文档系统和其他子应用时,相关依赖又要单独管理,又有上述的症状
- 无法跨部门共享基建产物资产元数据
针对上述问题我们引入了 Monorepo 的概念,把以往的单一组件库拆分为职责更细化的包,架构更清晰,解耦,子应用隔离,并且做了严格的 CR,CI 机制(暂无 CD)、自动化构建、测试流水线、代码问题校验,工程化的最终目的是让业务开发可以 100% 聚焦在业务逻辑上精读《Monorepo 的优势》, 现代化前端应用为什么越来越离不开 Monorepo
- umi4.x: 快速构建 React 应用,react(V18.2),router(V6),集成 auto import, 微前端等插件。
- TypeScript: 所有代码提供强类型支持
- state management: Umi Model & Valtio
- unocss: 按需原子化 CSS 编译
- ant5.x: 快速研发企业级中后台产品, 开箱即用的高质量 React 组件
- theme | layout: 完全兼容新版 antd5 特性,支持自定义配置主题,主题 token 接入 unocss 和 css,less 变量, 路由keep-alive 等。
- dumi2.x: 为组件开发场景而生的静态站点框架
- father: 帮助开发者更高效、高质量地研发 NPM 包、生成构建产物、再完成发布。
- commontLint: 让你的 commits 更有意义
- jest: 优雅、简洁的 JavaScript 测试框架
- proComponents: 页面级组件让中后台开发更简单
- CI / CD: 一整套发布操作流自动化流程, 打包构建 =>跑测试用例 => 选择发包(多个)=> 选择升级的主版本包 => 打版本 tag => 生成日志 change-log => 写入到 dumi 文档 => 发布 npm
- monorepos: 包和应用划分清晰,跨应用复用代码,按需安装,支持纯净模式,仅安装主应用和相关包依赖
- dev | build: 优化 dev & build 配置,无需担心打包相关问题和 dev 环境的研发体验。
- vscode integrate: 适配研发插件 monorepo-workspace,快速铺平应用,优化 commit 显示,加速研发效率
- vscode cofig:针对该项目特有的编辑器的配置优化,如多文件折叠,autosave...
- pwa: 支持离线访问,独立安装,缓存机制等wrokbox功能,增加首屏的打开速度。
- search: 支持全文内容动态拼音检索,纠错检索等。
- auto-import: 接入unplugin-auto-import插件,在应用中所有关于 react, antd, proComponents, ahooks, antd/icons 中的 api 可以不用导入直接使用,插件会自动导入需要的 API;
- CRUD: 丰富的业务组件,覆盖常用业务
- final: 一直都在持续更新中,只为更快更好的研发体验...
- @vis/utils 工具库,常用的工具函数或者 hooks 等,如 transformData,uuid,timeFormat....
- @vis/test 这里你可以做任意操作,如测试 CI 自动化脚本,功能相关的东西,总之就是随便玩
- @vis/charts 基于antv下大屏画布或者仪表板图表库二次封装后的组件,如:条形进度图,词云图,饼图等...
- @vis/components 存放功能性组件,更偏向系统功能,如右键菜单,拖拽改变布局宽高...
- @vis/common 业务相关通用组件, 如 二次封装,request 拦截等...
- @vis/decorator 装饰器,包含 svg 渲染的所有动画和装饰,相比图片或者动图,可随意放大缩小,且轻量级。
防止后期主应用过大增加 dev 和编译负担,我们把以往的主应用下不相关的部分拆分成了独立的项目,然后使用微前端和模块联邦来对接子应用(代码共享和状态管理),这样整个应用能 hold 住未来不断扩张的业务线和人员开发,也不会出现在不同应用中组件库代码被重复打包。我们特意将组件库代码从主应用中抽离出来,每个独立的子应用共享主应用内导出的 exposes 文件夹下的模块。
- [/project/template]子应用模版
我们所有的包管理都强制使用pnpm,在 monorepo 架构之上,pnpm 能极大发挥他的作用(设计初期就很好的考虑了当前复杂项目的痛点),相比 yarn 和 npm,pnpm 能节约磁盘空间并提升安装速度,切避免了关于深度嵌套包的一些意外情况,如果你还没有接触了解过 pnpm,可以看看相关文章, 而且当前已有众多前端团队和大部分主流开源项目抛弃 npm,yarn,开始接入 pnpm。
npm pure-install
纯净模式,仅安装主应用和 packages 的依赖, 忽略所有子应用依赖pnpm i
安装npm run dev
# 运行主项目npm run build
# 打包主项目npm run dev-project
# 运行项目下的子应用(visual, dashboard, dataModel, ....)npm run build-lib
# 懒加载打包(esm 格式)package 下所有库(保留文件的引用关系),能解耦主应用代码,避免重复打包npm run build-dist
# 打包生产环境下 package 下所有库(压缩,生成单文件和 css),适用于给其他团队项目中使用,仅忽略 antd,proComponents,moment 库npm run build-selectPkg
# 手动选择打包,防止后期包太多的情况全部打包消耗过多资源和时间npm run doc
# 运行项目文档, 包含组件库文档和项目说明等npm run test
# 跑测试用例
npm run release
提供界面交互可视化自动发包npm run release:only
手动修改版本号后发包 查看更多
为了很好的区分应用和对应的路由,我们建议所有子应用使用 hash 路由开发,这样就能统一路由风格,增加路由的可读性,且能减少很多不必要的 nginx 配置 😊
http://10.28.184.132:8088/dash/#/list?type=dashboard
地址拆分解析:
http://10.28.184.132:8088
- 主机地址/dash
- 路由的 history 用来区分子应用/#/list
- hash 路由参数为子应用自己的路由?type=dashboard
- 传参
- changeSets :发包工具
- husky 代码提交规范工具
- jest:自动化测试框架
- react chorme debug: react 调试 & 性能分析
- vscode monorepo workspace: monorepo 工程 vscode 插件,进一步优化你的开发体验
Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |