Skip to content

架构

特点

前端架构和后端还有所区别,自顶向下来说

  1. 系统级架构:对整个系统的描述,例如
    1. 前后端的协作方式 — 前后端分离
    2. 前后端的数据交互方式
    3. 前后端接口定义方式

  1. 应用级架构:对前端应用的描述,例如
    1. 使用哪个前端框架、版本 — Vue@3
    2. 状态管理、版本 — Vuex@4
    3. UI 库、版本 — Antd
  2. 模块级架构:对前端工程模块的描述,例如
    1. 如何拆分模块,按照什么粒度拆分
    2. 模块的测试如何实现
    3. 模块状态管理及模块间的数据传递
  3. 代码级架构:对代码规范的描述,例如
    1. 文件命名及管理
    2. 代码格式
    3. git 协作流程
    4. CI/CD

架构设计

什么是架构

架构就是整个系统的骨架、是整个系统构建的蓝图,后续的所有构建必须依照与架构设计实施

架构设计的关键点

  1. 系统与系统之间的关系:例如 A 系统依赖 B 系统,C 系统和 D 系统互不
  2. 系统内,应用与应用之间的关系:例如前端和后端的数据交互、接口定义…,或者微前端的各个子系统关系
  3. 应用内架构:例如选择语言、框架、状态管理
  4. 规范:例如代码规范、git 协作规范、构建流程

架构设计流程

  1. 收集需求
    1. 收集相关利益者需求
    2. 寻找各方的平衡点,例如需求、代码质量、开发速度、战略等,采取折中的方案
    3. 跨功能性需求,例如后端的高并发、高可用、高性能
    4. 收集风险点
  2. 架构设计
  3. 架构验证

架构设计风格

  1. 分层设计:例如网络 OSI 层模型
  2. MVC:例如 Java 的 Spring
  3. MVVM:例如 Vue
  4. 发布订阅
  5. 管道和过滤器

架构设计方法

4+1 图发

  1. 系统视图
  2. 逻辑视图
  3. 物理视图
  4. 开发视图
  5. 场景

架构设计产物

  1. 架构图
  2. 技术选型
  3. 迭代计划
  4. 示例代码
  5. 测试策略
  6. 构建流程及部署

架构设计原则

  1. 不多不少:不要设计过于复杂的架构,但对需要的供能不能少
  2. 演进式:随着业务、技术需要,调整架构(进化
  3. 渐进式:修正以往的 BUG

架构实施

技术准备期

  1. 方案设计:与利益相关者沟通,设计方案
  2. 方案验证:对方法设计进行验证,例如可以建一个 demo 来验证
  3. 搭建完整的开发环境

业务回补期

  1. 文档沉淀
  2. 代码规范
  3. code review
  4. 测试

成长优化期

  1. 技术栈
  • 代码质量的提高
  • 测试的补全
  • 依赖的持续更新
  1. 架构优化

技术负责人的职责:

  1. 平衡业务进度和技术方案(代码质量和时间进度)
  2. 解决复杂和重要问题
  3. 帮助队员成长
  4. 从全局角度考虑整个项目的技术、业务问题

包含但不限于一下流程

方案设计 -> 方案落地(方案实施 -> 方案上线 -> 后期维护)

工作流设计

工作流设计最关键的就是自动化,流程自动化规范自动化是最好的了

  1. 代码规范
  • 命名规范
  • 语句规范
  1. 文档记录
  • README
  • 记录决策
  • 可视化文档
  • 提交记录
  • changelog
  1. 代码预处理
  2. 代码审视
  • 常规审视
  • 阻塞审视
  1. 测试
  • 单元测试:测试一个单元的行为,例如一个函数
  • 组件测试:测试组件行为
  • 服务测试:包含后端一起测试,整体和组件测试差不多
  • E2E 测试:模拟真实用户的测试,由于 E2E 测试较为复杂,应当考虑做核心功能或经常出错的功能
  1. 工具使用(代码质量测试)
  • sonar
  • checkStyle

构建流设计

依赖管理

yarn、npm、pnpm

*.lock

优化开发环境

  1. 项目启动速度
  2. 项目热更新速度

代码质量检测

  1. 提交前检测:通过 Client Hooks 对提交代码进行检测
  2. 提交后检测:通过 Server Hooks 对提交后的代码进行检测

编译、打包、部署自动化

  1. 手动部署
  2. 自动部署
  3. 持续部署

线上开关

  1. 根据 URL 或 header 参数来决定是否开启某些功能
  2. 根据 localstorage 来开启某些功能

灰度

AB

仓库的管理

Monorepo 和 Multirepo

这两种仓库管理模式,其实就是单个 repository 还是多个 reposity 的问题

我们将有个大项目细分为多个小项目,如果每个小项目都有自己的 reposity,即为 Multirepo(其实就是多个 git 地址),例如

git@github.com:github/A.git
git@github.com:github/B.git

Multirepo 有如下缺点

  1. 代码复用:代码复用繁琐,例如本地开发时需要 npm link,上线后可以抽离为 npm 包或直接引用 github

  2. 版本不一致:

    • 项目版本不一致:例如 A 项目内依赖的 B 项目可能是 1.0.0;C 项目依赖的 B 项目可能是 2.0.0
    • 依赖版本不一致:可能出现多个项目的同一个包版本不同,例如 A 项目 react 15.,B 项目 react 17.
  3. 基建(工程化)不一致:例如 A 项目使用 webpack,B 项目使用 rollup

  4. 项目地址难以寻寻找,如果不是长期维护可一时之间可能会懵逼

Monorepo 可以解决如下如上问题

  1. 代码存储于同一个 repository,不会出现找不到包的问题,代码复用也可以解决
  2. 同时使用的是最新的代码,不会存在版本不一致的问题;对于公共依赖都是提升到根 package.json,也不会出现依赖版本不一致的问题
  3. 工程一致性,一个 repo 一般是用一个工具构建

缺点

  1. 项目之间紧密耦合
  2. 项目过大时,对于 IDEA 支持不友好,例如 webstorm 这种 IDEA,
  3. 当项目极大时, 就需要更加复杂的“依赖追踪、发布、构建”等问题了,因为项目足够大的情况下,一次性全量发版花费时间过长,尤其是当一个 git status 都要花费几分钟时

目前存在多种的 monorepo 管理工具,常见的如下,

  • Pnpm workspace:轻量,支持多包管理、依赖提升。
  • Lerna:较早出现的工具,社区成熟,支持多包管理、依赖提升。适合简单多包发布场景
  • Nx:功能强大,支持多包管理、多语言、缓存、多任务调度等等。但功能过于复杂,学习成本高
  • Turborepo(Vercel):轻量高效,支持多包管理、构建缓存、多任务调度
  • Rush(微软):功能强大,支持多包管理、增量构建,但功能过于复杂,学习成本高
  • Bazel(Google):功能强大,支持多包管理、多语言、复杂任务调度、构建缓存,但功能过于复杂,学习成本高
  1. 针对个人项目、小型项目,可采用 Pnpm workspace, Turborepo, Lerna
  2. 针对企业级项目,可采用 Nx, Rush, Bazel
  3. 针对多语言项目,可采用 Nx, Bazel

git submodule