大型项目的挑战
┌──────────────────────────────────────────────────────────────┐
│ 大型前端项目的典型挑战 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 代码规模 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 100+ 页面 │ 1000+ 组件 │ 10万+ 行代码 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 团队规模 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 10+ 开发者 │ 多团队协作 │ 代码风格不统一 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 技术债 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 框架升级困难 │ 依赖混乱 │ 文档缺失 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 性能问题 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 首屏加载慢 │ Bundle 体积大 │ 内存泄漏 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
分层架构
前端分层模型
┌──────────────────────────────────────────────────────────────┐
│ 前端分层架构 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 视图层 (View) │ │
│ │ React Components / Vue Components │ │
│ │ 负责 UI 渲染和用户交互 │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────────┐ │
│ │ 业务层 (Business) │ │
│ │ Hooks / Composables / Mixins │ │
│ │ 负责业务逻辑编排 │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────────┐ │
│ │ 服务层 (Service) │ │
│ │ API 调用 / 状态管理 / 缓存逻辑 │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────────┐ │
│ │ 数据层 (Data) │ │
│ │ HTTP Client / WebSocket / LocalStorage │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
目录结构设计
src/
├── app/ # 应用入口
│ ├── App.tsx
│ ├── router.ts
│ └── main.tsx
│
├── pages/ # 页面组件
│ ├── Home/
│ ├── Dashboard/
│ ├── UserProfile/
│ └── ...
│
├── components/ # 共享组件
│ ├── ui/ # 基础 UI 组件
│ │ ├── Button/
│ │ ├── Input/
│ │ ├── Modal/
│ │ └── ...
│ │
│ ├── business/ # 业务组件
│ │ ├── UserCard/
│ │ ├── ProductList/
│ │ └── ...
│ │
│ └── layout/ # 布局组件
│ ├── Header/
│ ├── Sidebar/
│ └── ...
│
├── features/ # 按功能模块划分(可选)
│ ├── auth/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── services/
│ │ └── types/
│ │
│ ├── users/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── services/
│ │ └── types/
│ └── ...
│
├── hooks/ # 全局 Hooks
│ ├── useAuth.ts
│ ├── useTheme.ts
│ └── useAsync.ts
│
├── services/ # API 服务
│ ├── apiClient.ts
│ ├── authService.ts
│ ├── userService.ts
│ └── ...
│
├── stores/ # 状态管理
│ ├── authStore.ts
│ ├── userStore.ts
│ └── ...
│
├── utils/ # 工具函数
│ ├── format.ts
│ ├── validate.ts
│ └── ...
│
├── constants/ # 常量
│ ├── api.ts
│ └── config.ts
│
├── types/ # 类型定义
│ ├── api.ts
│ ├── user.ts
│ └── ...
│
└── styles/ # 全局样式
├── variables.scss
├── mixins.scss
└── global.scss
微前端架构
什么是微前端
微前端是将微服务的思想应用于前端,让多个团队可以独立开发、部署不同前端应用。
┌──────────────────────────────────────────────────────────────┐
│ 微前端架构示意图 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 主应用容器 │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │ │ 用户 │ │ 订单 │ │ 设置 │ │ │ │
│ │ │ │ 子应用 │ │ 子应用 │ │ 子应用 │ │ │ │
│ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 特点:独立部署、独立开发、技术栈无关 │
│ │
└──────────────────────────────────────────────────────────────┘
qiankun 实现
// 主应用 main.js
import { start qiankun } from 'qiankun';
// 注册子应用
registerMicroApps([
{
name: 'user-app',
entry: '//localhost:8081',
container: '#micro-container',
activeRule: '/user',
props: {
shared: window.__SHARED__
}
},
{
name: 'order-app',
entry: '//localhost:8082',
container: '#micro-container',
activeRule: '/order'
},
{
name: 'settings-app',
entry: '//localhost:8083',
container: '#micro-container',
activeRule: '/settings'
}
]);
// 启动
start({
prefetch: 'all', // 预加载
sandbox: {
strictStyleIsolation: true // 样式隔离
}
});
子应用配置
// 子应用(React) src/microApp/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
let root;
// 导出生命周期
export async function bootstrap() {
console.log('子应用启动');
}
export async function mount(props) {
console.log('子应用挂载', props);
root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
}
export async function unmount() {
console.log('子应用卸载');
root?.unmount();
root = null;
}
// 开发环境独立运行
if (!window.__POWERED_BY_QIANKUN__) {
bootstrap().then(mount);
}
性能预算
性能预算定义
// performance-budget.json
{
"budgets": [
{
"resourceType": "script",
"budget": 244, // KB
"tolerance": 10 // 允许超出 10KB
},
{
"resourceType": "image",
"budget": 170,
"tolerance": 10
},
{
"resourceType": "total",
"budget": 500,
"tolerance": 20
}
]
}
自动化性能检查
# .github/workflows/performance.yml
name: Performance Budget
on:
push:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Build
run: npm ci && npm run build
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v10
with:
configPath: './lighthouserc.json'
uploadArtifacts: true
Lighthouse 配置
// lighthouserc.json
{
"ci": {
"collect": {
"staticDistDir": "./dist",
"url": [
"http://localhost:3000/"
]
},
"assert": {
"assertions": {
"categories:performance": ["error", { "minScore": 0.8 }],
"categories:accessibility": ["error", { "minScore": 0.9 }],
"first-contentful-paint": ["warn", { "maxNumericValue": 2000 }],
"largest-contentful-paint": ["error", { "maxNumericValue": 4000 }],
"total-blocking-time": ["error", { "maxNumericValue": 500 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.25 }]
}
}
}
}
代码治理
ESLint 规则集
// eslint-config-custom/index.js
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended'
],
rules: {
// 强制使用函数式组件
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off',
// TypeScript
'@typescript-eslint/no-unused-vars': ['error', {
argsIgnorePattern: '^_',
varsIgnorePattern: '^_'
}],
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
// React
'react-hooks/exhaustive-deps': 'warn',
// 其他
'no-console': 'warn',
'prefer-const': 'error'
},
settings: {
react: {
version: 'detect'
}
}
};
Git Hooks
// husky 配置
// .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
// .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx commitlint --edit $1
// .husky/pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run type-check
npm run test
commitlint 配置
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', // 新功能
'fix', // 修复
'docs', // 文档
'style', // 格式
'refactor', // 重构
'perf', // 性能
'test', // 测试
'chore', // 构建/工具
'ci', // CI
'revert' // 回滚
]
],
'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']]
}
};
依赖管理
依赖审计
# 查看可更新的包
npm outdated
# 更新到最新兼容版本
npm update
# 更新到最新版本(可能破坏性变更)
npm install package@latest
# 交互式更新
npx npm-check-updates -u
依赖安全
# 检查漏洞
npm audit
npm audit --audit-level=high
# 自动修复
npm audit fix
# 使用 Snyk
npx snyk test
锁定文件
# package-lock.json vs yarn.lock vs pnpm-lock.yaml
# 推荐 pnpm:快、节省空间、支持 monorepo
文档体系
组件文档
// components/Button/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
title: 'UI/Button',
component: Button,
tags: ['autodocs'],
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'outline', 'ghost']
},
size: {
control: 'select',
options: ['sm', 'md', 'lg']
},
disabled: { control: 'boolean' },
loading: { control: 'boolean' }
}
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: {
variant: 'primary',
children: 'Primary Button'
}
};
export const Loading: Story = {
args: {
variant: 'primary',
loading: true,
children: 'Loading...'
}
};
API 文档
// services/userService.ts
/**
* 获取用户信息
* @param userId - 用户 ID
* @returns 用户信息
* @example
* ```ts
* const user = await getUser('123');
* console.log(user.name);
* ```
*/
export async function getUser(userId: string): Promise<User> {
const response = await apiClient.get(`/users/${userId}`);
return response.data;
}
技术债务管理
债务分类
| 类型 | 优先级 | 说明 |
|---|---|---|
| 架构类 | 高 | 需要重构核心代码 |
| 依赖类 | 中 | 过时的库/框架 |
| 代码类 | 低 | 代码质量问题 |
| 文档类 | 低 | 缺失的文档 |
债务处理流程
发现债务 → 评估影响 → 记录债务 → 安排迭代 → 偿还债务 → 验证
债务记录
# 技术债务
## 高优先级
### [架构] 状态管理重构
- 问题:当前 Redux 过于复杂,新人上手困难
- 影响:开发效率降低,新功能开发周期长
- 建议:迁移到 Zustand 或 Jotai
- 预估工作量:2 周
- 创建日期:2024-01-15
## 中优先级
### [依赖] 升级 React 18
- 问题:当前使用 React 16,部分新特性无法使用
- 影响:无法使用新 Hooks
- 建议:分阶段升级,先升级到 17
- 预估工作量:3 天
- 创建日期:2024-02-01
这一章想说的
大型项目架构设计:
- 分层架构:视图层、业务层、服务层、数据层分离
- 目录结构:按功能或类型组织,清晰可维护
- 微前端:多团队协作、独立部署的解决方案
- 性能预算:用自动化工具确保性能不退化
- 代码治理:ESLint、Git Hooks、文档体系
好的架构让项目可持续迭代,坏的架构让项目举步维艰。