跳到正文
前端知识库
工程化

前端项目架构设计与选型

从分层边界、PC/移动端差异到测试发布闭环,建立可解释、可演进的前端架构决策方法。

7 分钟工程化 · 架构 · Vue · TypeScript · 测试 · 发布 · 选型

前端项目架构设计与选型

整理来源:第五篇 - 面试利器之前端技术架构设计实操.pdf 的分层图与 PC/移动端模板清单,以及 第四篇 - 面试高频踩坑解析.pdf 的工程化追问。这里把依赖清单改写为约束、边界和验证方法,过滤机构、课程、报名信息和无法复核的效果数字。

1. 架构题先回答约束

架构不是把库名排成一列,而是让变化被限制在合适的边界内。开始设计前先确认:

  • 运行环境:纯浏览器、SSR、桌面壳还是移动 WebView;是否需要离线和旧浏览器兼容。
  • 产品形态:管理端、内容站、交互应用或组件库;页面数量、权限模型和 SEO 要求。
  • 数据边界:服务端状态、客户端 UI 状态、缓存、表单草稿和敏感凭据分别由谁拥有。
  • 团队与交付:包/目录边界、多人并行方式、测试门禁、发布渠道和回滚入口。
  • 可观测性:要验证的用户指标、错误上下文、版本标识和降级路径。

没有这些约束时,所谓“最佳技术栈”只是偏好。面试中应先给一个可运行的最小方案,再说在约束变化时如何替换。

2. 用依赖方向表达分层

资料中的展示层、业务逻辑层和数据访问层可以落成下面的依赖方向:

页面/组件 -> ViewModel/DTO 映射 -> 用例与领域规则
                                  -> 仓储/数据访问接口
                                         -> HTTP、Storage、数据库或原生能力

分层的重点是依赖方向,而不是层数:

  • 展示层负责路由入口、可访问性、用户交互和 ViewModel,不直接拼接数据库字段。
  • 应用/领域层负责用例、状态转移、校验和错误语义,不依赖具体 UI 库。
  • 数据访问层负责 API 客户端、缓存、序列化和重试策略,通过接口向上提供能力。
  • 基础设施层负责浏览器 API、日志、配置、监控和第三方适配;不能把密钥下发到浏览器。

DTO、BO、VO、PO 等名词只有在边界真的不同的时候才有价值。若只是复制对象改名,会增加维护成本;若外部 API 经常变化,单独的映射层可以隔离后端契约和页面模型。

3. PC 与移动端模板如何取舍

常见 Vue 模板会组合 Router、文件系统路由、布局插件、Pinia、TypeScript、Markdown/代码高亮、国际化、head 管理和 Vitest;移动端可能再加入触摸友好的组件库。它们是候选能力,不是必须成套安装的清单:

关注点 PC 管理端 移动端 Web 选型证据
布局 多栏、表格、键盘操作和可调整面板 单列、手势、窄屏和系统回弹 关键页面交互原型与可访问性测试
路由/布局 文件系统路由可减少重复声明,但仍需权限守卫 需要处理返回栈、深链和网络恢复 路由状态图、刷新/返回测试
状态 筛选条件、批量操作和 URL 同步较多 草稿、滚动位置和离线恢复更重要 状态所有权表与持久化策略
UI 组件 桌面密度、焦点和拖拽 触摸命中区、键盘替代和安全区 真实设备交互测试
内容/SEO Markdown 组件和文档头可能是核心能力 关注首屏、带宽和渐进增强 SSR/性能预算与降级实验
测试 单元、组件交互、浏览器 E2E 加入触摸、旋转、低带宽和页面恢复 稳定的 CI 场景矩阵

例如,文件系统路由只解决路由发现和组织,不自动解决权限;Pinia 只解决一类客户端状态,不代替服务端缓存一致性;Markdown 渲染器必须配合 HTML 消毒和内容来源约束。

3.1 工具职责与验证边界

把模板中的工具按“谁拥有哪类变化”拆开,面试时才能从库名讲到实际架构:

工具/能力 应负责什么 不应替代什么 最小验证
Router + 文件系统路由/布局插件 路由发现、布局组合、参数解析和导航状态 服务端授权、业务状态和数据缓存 深链、刷新、前进后退、未授权跳转
Pinia 或局部 store 客户端 UI、跨页面偏好和少量会话派生状态 服务端查询缓存、事务和最终权限判断 订阅粒度、刷新恢复、登出清理、SSR 隔离
Markdown + 代码高亮 受信内容的结构化渲染和阅读体验 HTML 安全、任意组件执行和用户输入消毒 恶意标签/链接、代码块、目录锚点和 SSR 输出
i18n + head 管理 locale 选择、文案回退、标题和 meta 同步 URL 权限、数据翻译和 SEO 的全部保证 切换语言、刷新深链、缺失 key、服务端/客户端一致性
VueUse/平台适配器 封装重复的浏览器、交互和生命周期逻辑 隐藏副作用、权限或资源释放责任 SSR/浏览器分支、卸载清理、异常和降级
移动端组件库 触摸命中区、手势、安全区和移动控件语义 桌面布局、业务状态和跨端数据协议 真机触摸、旋转、低带宽、键盘替代和可访问性
Vitest 纯函数、状态转移、适配器和组件局部行为 真实浏览器导航、网络链路和发布产物 边界输入、异步取消、稳定 fixture 和覆盖风险
Cypress 等浏览器 E2E 真实路由、权限、关键用户流程和回归 单元级所有分支、性能基准和生产监控 隔离数据、网络 stub、可访问定位器、截图/trace

这张表也说明了为什么不能把“安装了测试框架”写成“有测试保障”:每一层都要对应风险、夹具和失败后的处理方式。PC 与移动端可以共享领域用例和设计令牌,但应分别验证交互和渲染边界,避免复制一套页面后再用 CSS 补救所有差异。

4. 技术选型记录(ADR)

每个会影响公共边界的选择都应留下短记录:

背景:多个页面需要共享筛选条件,并支持刷新后恢复。
约束:筛选可分享、服务端可复现,不能把令牌放进 URL。
选项:仅组件状态、Pinia、URL + 页面状态的组合。
决定:可分享的筛选进入 URL,瞬时 UI 状态留在页面;请求缓存由请求层负责。
验证:深链、刷新、前进后退、并发请求和权限变化测试。
回滚:保留旧参数解析一段兼容期,失败时回退到默认筛选。

选型评审至少比较兼容性、包体/启动成本、调试能力、团队熟悉度、迁移成本和失败时的降级方式。不要用未经复核的“快多少”“节省多少”替代基准;没有测量时写成待验证假设。

5. 状态、路由和数据的边界

建议先画状态所有权,而不是先决定状态库:

状态 事实来源 生命周期 常见风险
URL 查询参数 地址栏/路由 可分享、可回退 把敏感信息写入历史记录
服务端数据 API/缓存层 可失效、可重取 竞态响应覆盖新请求
页面 UI 状态 组件或局部 store 页面级 全局 store 过度耦合
表单草稿 表单模型/Storage 受控持久化 版本迁移和隐私泄露
会话凭据 受控认证边界 会话级 XSS、日志和跨端同步泄露

请求层应定义取消、超时、重试、去重和错误码;页面只消费语义化结果。路由守卫负责导航前置检查,服务端仍必须做最终授权,不能把前端隐藏菜单当成安全边界。

6. 从代码到发布的质量闭环

一套可交付的架构至少包含:

  1. 类型检查和 Lint:配置、生成目录和运行环境边界可审查。
  2. 单元/组件测试:验证状态转移、错误和键盘/触摸交互。
  3. 浏览器 E2E 与 SSR/水合检查:验证真实路由、权限和首屏标记。
  4. 可复现构建:锁定依赖和 Node/包管理器版本,产物由当前提交生成。
  5. 发布治理:版本标识、灰度或分批策略、错误监控、回滚入口和兼容窗口。

组件库还要检查 exports、类型声明、CSS 副作用和消费者安装;详见前端组件库工程化。监控 SDK、缓存和灰度策略可结合前端稳定性跨端交互与发布治理

7. 架构评审清单

  • 每个跨层调用是否有明确的接口和错误语义?
  • 展示层是否能在不改领域规则的情况下替换 UI 框架?
  • 服务端数据、UI 状态和凭据是否由不同边界管理?
  • 第三方库是否有替换成本、版本策略和公开入口?
  • 关键路径是否有最小实验、测试、监控字段和回滚方案?
  • PC/移动端的差异是否来自真实交互约束,而不是复制两份代码?
  • 新增一层是否真正隔离了变化;若没有,是否应删掉这层?

相关专题:技术误区与验证Vite 面试进阶低代码系统架构