架构
特点
前端架构和后端还有所区别,自顶向下来说
- 系统级架构:对整个系统的描述,例如
- 前后端的协作方式 — 前后端分离
- 前后端的数据交互方式
- 前后端接口定义方式
…
- 应用级架构:对前端应用的描述,例如
- 使用哪个前端框架、版本 — Vue@3
- 状态管理、版本 — Vuex@4
- UI 库、版本 — Antd
- 模块级架构:对前端工程模块的描述,例如
- 如何拆分模块,按照什么粒度拆分
- 模块的测试如何实现
- 模块状态管理及模块间的数据传递
- 代码级架构:对代码规范的描述,例如
- 文件命名及管理
- 代码格式
- git 协作流程
- CI/CD
架构设计
什么是架构
架构就是整个系统的骨架、是整个系统构建的蓝图,后续的所有构建必须依照与架构设计实施
架构设计的关键点
- 系统与系统之间的关系:例如 A 系统依赖 B 系统,C 系统和 D 系统互不
- 系统内,应用与应用之间的关系:例如前端和后端的数据交互、接口定义…,或者微前端的各个子系统关系
- 应用内架构:例如选择语言、框架、状态管理
- 规范:例如代码规范、git 协作规范、构建流程
架构设计流程
- 收集需求
- 收集相关利益者需求
- 寻找各方的平衡点,例如需求、代码质量、开发速度、战略等,采取折中的方案
- 跨功能性需求,例如后端的高并发、高可用、高性能
- 收集风险点
- 架构设计
- 架构验证
架构设计风格
- 分层设计:例如网络 OSI 层模型
- MVC:例如 Java 的 Spring
- MVVM:例如 Vue
- 发布订阅
- 管道和过滤器
架构设计方法
4+1 图发
- 系统视图
- 逻辑视图
- 物理视图
- 开发视图
- 场景
架构设计产物
- 架构图
- 技术选型
- 迭代计划
- 示例代码
- 测试策略
- 构建流程及部署
架构设计原则
- 不多不少:不要设计过于复杂的架构,但对需要的供能不能少
- 演进式:随着业务、技术需要,调整架构(进化)
- 渐进式:修正以往的 BUG
架构实施
技术准备期
- 方案设计:与利益相关者沟通,设计方案
- 方案验证:对方法设计进行验证,例如可以建一个 demo 来验证
- 搭建完整的开发环境
业务回补期
- 文档沉淀
- 代码规范
- code review
- 测试
成长优化期
- 技术栈
- 代码质量的提高
- 测试的补全
- 依赖的持续更新
- 架构优化
技术负责人的职责:
- 平衡业务进度和技术方案(代码质量和时间进度)
- 解决复杂和重要问题
- 帮助队员成长
- 从全局角度考虑整个项目的技术、业务问题
包含但不限于一下流程
方案设计 -> 方案落地(方案实施 -> 方案上线 -> 后期维护)
工作流设计
工作流设计最关键的就是自动化,流程自动化和规范自动化是最好的了
- 代码规范
- 命名规范
- 语句规范
- 文档记录
- README
- 记录决策
- 可视化文档
- 提交记录
- changelog
- 代码预处理
- 代码审视
- 常规审视
- 阻塞审视
- 测试
- 单元测试:测试一个单元的行为,例如一个函数
- 组件测试:测试组件行为
- 服务测试:包含后端一起测试,整体和组件测试差不多
- E2E 测试:模拟真实用户的测试,由于 E2E 测试较为复杂,应当考虑做核心功能或经常出错的功能
- 工具使用(代码质量测试)
- sonar
- checkStyle
构建流设计
依赖管理
yarn、npm、pnpm
*.lock
优化开发环境
- 项目启动速度
- 项目热更新速度
代码质量检测
- 提交前检测:通过 Client Hooks 对提交代码进行检测
- 提交后检测:通过 Server Hooks 对提交后的代码进行检测
编译、打包、部署自动化
- 手动部署
- 自动部署
- 持续部署
线上开关
- 根据 URL 或 header 参数来决定是否开启某些功能
- 根据 localstorage 来开启某些功能
灰度
AB
仓库的管理
Monorepo 和 Multirepo
这两种仓库管理模式,其实就是单个 repository 还是多个 reposity 的问题
我们将有个大项目细分为多个小项目,如果每个小项目都有自己的 reposity,即为 Multirepo(其实就是多个 git 地址),例如
git@github.com:github/A.gitgit@github.com:github/B.gitMultirepo 有如下缺点
-
代码复用:代码复用繁琐,例如本地开发时需要 npm link,上线后可以抽离为 npm 包或直接引用 github
-
版本不一致:
- 项目版本不一致:例如 A 项目内依赖的 B 项目可能是 1.0.0;C 项目依赖的 B 项目可能是 2.0.0
- 依赖版本不一致:可能出现多个项目的同一个包版本不同,例如 A 项目 react 15.,B 项目 react 17.
-
基建(工程化)不一致:例如 A 项目使用 webpack,B 项目使用 rollup
-
项目地址难以寻寻找,如果不是长期维护可一时之间可能会懵逼
Monorepo 可以解决如下如上问题
- 代码存储于同一个 repository,不会出现找不到包的问题,代码复用也可以解决
- 同时使用的是最新的代码,不会存在版本不一致的问题;对于公共依赖都是提升到根 package.json,也不会出现依赖版本不一致的问题
- 工程一致性,一个 repo 一般是用一个工具构建
缺点
- 项目之间紧密耦合
- 项目过大时,对于 IDEA 支持不友好,例如 webstorm 这种 IDEA,
- 当项目极大时, 就需要更加复杂的“依赖追踪、发布、构建”等问题了,因为项目足够大的情况下,一次性全量发版花费时间过长,尤其是当一个
git status都要花费几分钟时
目前存在多种的 monorepo 管理工具,常见的如下,
- Pnpm workspace:轻量,支持多包管理、依赖提升。
- Lerna:较早出现的工具,社区成熟,支持多包管理、依赖提升。适合简单多包发布场景
- Nx:功能强大,支持多包管理、多语言、缓存、多任务调度等等。但功能过于复杂,学习成本高
- Turborepo(Vercel):轻量高效,支持多包管理、构建缓存、多任务调度
- Rush(微软):功能强大,支持多包管理、增量构建,但功能过于复杂,学习成本高
- Bazel(Google):功能强大,支持多包管理、多语言、复杂任务调度、构建缓存,但功能过于复杂,学习成本高
- 针对个人项目、小型项目,可采用 Pnpm workspace, Turborepo, Lerna
- 针对企业级项目,可采用 Nx, Rush, Bazel
- 针对多语言项目,可采用 Nx, Bazel