Frontend Architecture

v1.0.0

设计大型前端应用的可扩展架构,包括项目结构、模块边界、依赖管理、代码分割及技术债预防策略。

0· 25·0 current·0 all-time
bywangzhiming@wangzhiming1999
Security Scan
Capability signals
CryptoCan make purchases
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
技能名称与描述一致:提供大型前端架构设计、项目结构、模块边界、代码分割和技术债管理等。SKILL.md 包含与此目的直接相关的示例结构、ESLint 规则、Vite/Next 配置片段、ADR 模板和重构策略,所需资源(无二进制、无环境变量)与目标相符。
Instruction Scope
运行时说明只包含架构问诊步骤、配置示例与代码片段,未指示读取系统文件、访问外部服务或传送敏感信息。没有模糊授权(如“随意收集上下文”)或要求访问不相关的凭据。
Install Mechanism
无安装规范、无代码文件需要写入或执行;这是低风险的 instruction-only 技能(不会在系统上下载或安装第三方软件)。
Credentials
不要求任何环境变量、凭据或配置路径;SKILL.md 也未引用未声明的敏感 env 或密钥,所需权限与技能功能比例合理。
Persistence & Privilege
flags 显示 always:false 且默认允许用户或模型调用(平台默认)。技能不会请求永久驻留或修改其它技能/系统配置。
Assessment
这是一个文档/指导型技能,主要给出架构建议和可复制的配置片段。若要使用: - 在将示例代码粘贴到真实项目之前审阅并在隔离环境中测试(ESLint 规则、Vite/Next 配置、manualChunks 等)。 - 注意将通用建议按团队规模和业务约束调整;不要盲目复制配置。 - 源信息显示为 instruction-only,作者/主页信息指向 GitHub,但来源未完全验证;如果你关心维护与更新,先在 GitHub 仓库查看提交历史与作者信誉。 总体上该技能内部一致、无过度权限或隐私请求,适合用作架构咨询模板。

Like a lobster shell, security has layers — review code before you run it.

latestvk97e6atj6ybajectwawry280m98562bc
25downloads
0stars
1versions
Updated 10h ago
v1.0.0
MIT-0

前端架构设计(Frontend Architecture)

为大型前端应用设计可扩展的架构——不是"用什么框架",而是如何组织代码、划分模块、管理依赖,让项目在 2 年后还能维护。

触发场景

  • 「新项目技术选型」「从零搭建前端架构」
  • 「项目越来越乱」「不知道代码该放哪」「模块耦合严重」
  • 「多团队协作」「微前端」「代码复用」
  • 「技术债务」「重构策略」「如何避免架构腐化」

执行流程

1. 先搞清楚项目规模和约束

不要一上来就给"最佳实践",先问清楚:

问题为什么重要影响的决策
团队规模?3 人和 30 人的架构完全不同是否需要严格的模块边界、代码审查流程
预期生命周期?3 个月 MVP 和 3 年产品的架构不同是否需要考虑扩展性、技术债管理
性能要求?ToB 后台和 ToC 电商的性能要求不同SSR/SSG、代码分割策略、CDN 策略
是否多团队?影响模块划分和发布策略Monorepo、微前端、API 契约
现有技术栈?存量项目迁移成本高渐进式重构 vs 推倒重来

2. 项目结构设计

小型项目(< 3 人,< 6 个月):

src/
├── components/       # 所有组件
├── pages/           # 路由页面
├── hooks/           # 自定义 hooks
├── utils/           # 工具函数
├── api/             # API 请求
└── types/           # 类型定义

中型项目(3-10 人,6 个月 - 2 年):

src/
├── features/              # 按功能域划分
│   ├── auth/
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── api/
│   │   ├── types.ts
│   │   └── index.ts      # 导出公共接口
│   ├── dashboard/
│   └── settings/
├── shared/                # 跨 feature 共享
│   ├── components/       # 通用组件(Button、Modal)
│   ├── hooks/
│   ├── utils/
│   └── types/
├── app/                   # 应用层(路由、布局、全局状态)
│   ├── routes/
│   ├── layouts/
│   └── providers/
└── lib/                   # 第三方库封装
    ├── axios.ts
    ├── react-query.ts
    └── analytics.ts

大型项目(10+ 人,2 年+):

packages/                  # Monorepo
├── apps/
│   ├── web/              # 主应用
│   ├── admin/            # 管理后台
│   └── mobile/           # 移动端(可选)
├── features/             # 业务功能包
│   ├── auth/
│   ├── payment/
│   └── analytics/
├── ui/                   # 设计系统
│   ├── components/
│   ├── tokens/
│   └── themes/
├── shared/               # 共享工具
│   ├── utils/
│   ├── types/
│   ├── hooks/
│   └── api-client/
└── config/               # 共享配置
    ├── eslint/
    ├── tsconfig/
    └── tailwind/

3. 模块边界与依赖规则

分层架构(推荐):

app/          # 应用层:路由、布局、全局状态
  ↓ 可以依赖
features/     # 功能层:业务逻辑
  ↓ 可以依赖
shared/       # 共享层:通用组件、工具
  ↓ 可以依赖
lib/          # 基础设施层:第三方库封装

依赖规则(用 ESLint 强制):

// .eslintrc.js
{
  rules: {
    'no-restricted-imports': ['error', {
      patterns: [
        {
          group: ['@/features/*'],
          message: 'shared/ 不能依赖 features/'
        },
        {
          group: ['@/features/auth/*'],
          importNames: ['*'],
          message: 'features 之间不能直接依赖,通过 shared/ 或事件通信'
        }
      ]
    }]
  }
}

feature 之间的通信:

// ❌ 错:feature A 直接导入 feature B
import { useUserStore } from '@/features/auth/store'

// ✅ 对:通过 shared 层暴露接口
// shared/stores/user.ts
export { useUserStore } from '@/features/auth/store'

// 或用事件总线解耦
// shared/events.ts
export const eventBus = mitt()
// feature A
eventBus.emit('user:logout')
// feature B
eventBus.on('user:logout', handleLogout)

4. 代码分割策略

分割粒度的决策:

场景策略原因
路由页面每个页面一个 chunk用户不会一次访问所有页面
大型依赖(echarts、pdf.js)单独 chunk不是所有页面都需要
低频功能(导出、打印)懒加载大多数用户不会用
通用组件(Button、Modal)打进主 chunk几乎每个页面都用,拆了反而多请求

Next.js App Router 的分割:

// app/dashboard/page.tsx
import { Suspense } from 'react'
import dynamic from 'next/dynamic'

// 路由级自动分割,不需要手动 dynamic
export default function DashboardPage() {
  return <DashboardContent />
}

// 大型图表库按需加载
const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
  loading: () => <ChartSkeleton />,
  ssr: false,  // 不在服务端渲染
})

// 低频功能懒加载
const ExportModal = dynamic(() => import('./ExportModal'))

Vite 的手动分包:

// vite.config.ts
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor-react': ['react', 'react-dom', 'react-router-dom'],
          'vendor-ui': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu'],
          'vendor-charts': ['echarts', 'recharts'],
        }
      }
    }
  }
}

5. 技术选型决策框架

不要凭感觉选,用决策矩阵:

维度权重方案 A方案 B方案 C
学习曲线20%864
生态成熟度25%975
性能20%798
团队熟悉度15%953
社区活跃度10%876
迁移成本10%689
加权总分7.857.155.85

关键技术选型的决策点:

框架选择(React vs Vue vs Svelte):

  • 团队已有技能 > 框架本身优劣
  • ToB 后台、数据密集 → React(生态最完善)
  • 快速原型、小团队 → Vue(上手快)
  • 性能极致要求 → Svelte(编译时优化)

状态管理(Zustand vs Redux vs Jotai):

  • 简单全局状态 → Zustand
  • 复杂业务逻辑、需要中间件 → Redux Toolkit
  • 原子化状态、细粒度更新 → Jotai

样式方案(Tailwind vs CSS Modules vs CSS-in-JS):

  • 快速开发、设计系统 → Tailwind
  • 组件库、样式隔离 → CSS Modules
  • 动态主题、运行时样式 → CSS-in-JS(Stitches/Panda)

6. 技术债管理

技术债的分类:

类型特征处理策略
架构债模块耦合、分层混乱渐进式重构,设边界
代码债重复代码、命名混乱日常重构,code review
测试债覆盖率低、测试脆弱新功能必须有测试,存量逐步补
依赖债过时依赖、安全漏洞定期升级,用 Dependabot
文档债文档过时、缺失重要决策必须记录 ADR

ADR(Architecture Decision Record)模板:

# ADR-001: 选择 Zustand 作为状态管理方案

## 状态
已决定

## 背景
项目需要全局状态管理,主要用于主题、用户信息、通知等 UI 状态。

## 决策
选择 Zustand,不用 Redux。

## 理由
- 代码量少(Redux 需要 action/reducer/selector,Zustand 直接 set)
- 性能好(细粒度订阅,不需要 reselect)
- 学习曲线低(团队新人多)
- 不需要 Redux 的中间件生态(没有复杂异步逻辑)

## 后果
- 正面:开发效率高,代码简洁
- 负面:如果未来需要时间旅行调试,需要额外配置
- 缓解:用 Redux DevTools 扩展监控 Zustand

7. 渐进式重构策略

什么时候重构,什么时候重写:

场景策略原因
代码质量差但架构清晰渐进式重构风险低,可持续交付
架构腐化严重绞杀者模式(Strangler Fig)新功能用新架构,旧功能逐步迁移
技术栈过时且无法升级重写继续维护成本 > 重写成本

绞杀者模式示例(微前端):

旧应用(legacy.example.com)
  ├── /dashboard  → 保留
  ├── /settings   → 迁移到新应用
  └── /reports    → 迁移到新应用

新应用(app.example.com)
  ├── /settings   → 新架构实现
  └── /reports    → 新架构实现

Nginx 路由:
  /settings → app.example.com
  /reports  → app.example.com
  /*        → legacy.example.com

架构反模式

反模式问题正确做法
过度设计3 人团队用微前端按当前规模设计,预留扩展点
没有边界所有代码在 src/ 平铺按功能域或分层组织
循环依赖A 导入 B,B 导入 A用 ESLint 检测,提取公共依赖到 shared
全局状态滥用所有状态都放 store状态尽量下沉,能放组件就不放 store
技术债不可见没有记录,靠口口相传用 ADR 记录重要决策,用 TODO 标记技术债

输出模板

## 前端架构方案

### 项目背景
- 团队规模:X 人
- 预期生命周期:X 年
- 性能要求:[ToB 后台 / ToC 高性能]
- 现有技术栈:[新项目 / 存量迁移]

### 技术选型
| 维度 | 方案 | 理由 |
|------|------|------|
| 框架 | React / Vue / Svelte | … |
| 状态管理 | Zustand / Redux / Jotai | … |
| 样式 | Tailwind / CSS Modules | … |
| 构建 | Vite / Next.js | … |

### 项目结构
[目录树 + 分层说明]

### 模块边界
- 依赖规则:[分层图]
- ESLint 规则:[no-restricted-imports 配置]

### 代码分割策略
- 路由级:每个页面一个 chunk
- 大型依赖:[列出需要单独分割的库]
- 懒加载:[列出低频功能]

### 技术债管理
- ADR 存放位置:docs/adr/
- 重构策略:[渐进式 / 绞杀者模式]

Comments

Loading comments...