项目做了一半想重写?这套前端架构让你少走3年弯路

0 阅读5分钟

你是不是经历过:项目写到一半,发现目录乱成毛线,组件互相依赖,改一个地方崩十个地方。想重写?老板说“没时间”。不重写?每天加班改bug。今天我们就来聊聊前端架构——不是大厂才需要的东西,而是让你的项目能撑过3年迭代的“骨架”。看完你就能搭出一个即使团队换了几拨人,代码依然整洁的项目。

前言

盖房子要先打地基、搭框架,再砌墙、装修。前端也一样。很多人上来就写组件,写到一半发现状态管理乱、API调用散落各处、样式冲突、路由不知道怎么组织……最后项目就像一栋歪歪扭扭的危房,加个新功能都怕塌。

架构不是“过度设计”,而是让你在项目初期花20%的时间,省掉未来80%的痛苦。今天我们就从零开始,搭一套能支撑中大型项目的前端架构。

一、技术选型:别跟风,看需求

架构的第一步是选技术。但记住:没有最好的技术,只有最合适的

1. 框架选什么?

  • React:生态最丰富,适合复杂交互、需要高度定制化的项目。学习曲线平缓,但需要自己搭配路由、状态管理。
  • Vue:上手快,模板直观,适合中小项目或团队以Java/PHP为主。官方生态完整(Vue Router、Pinia)。
  • Angular:大而全,适合大型企业级应用,但学习曲线陡峭。

建议:如果不是特殊需求,React或Vue二选一。团队熟悉哪个用哪个。

2. 状态管理

  • React:简单项目用Context + useReducer;中等项目用Zustand(轻量);大项目用Redux Toolkit。
  • Vue:Vue 3 推荐 Pinia(比Vuex更简单)。

3. 构建工具

  • Vite:首选,快。除非你要兼容IE或需要特殊插件,否则别用Webpack了。

4. 类型系统

  • TypeScript:必选。别犹豫,就算小项目也能减少一半的运行时bug。

5. UI组件库

  • 内部后台系统:Ant Design、Element Plus、Semi Design。
  • 面向C端需定制:自己封装基础组件库,或用Tailwind CSS + 无头组件(Headless UI)。

二、目录结构:一眼就知道代码在哪

一个好的目录结构,新人进来10分钟就能找到要改的文件。推荐分层结构(以React为例):

src/
├── api/            # API请求层
│   ├── request.ts  # axios实例配置
│   ├── user.ts     # 用户相关接口
│   └── product.ts
├── assets/         # 静态资源(图片、字体)
├── components/     # 通用组件(按钮、弹窗、表格)
│   ├── Button/
│   │   ├── index.tsx
│   │   ├── Button.module.css
│   │   └── types.ts
│   └── Modal/
├── hooks/          # 自定义Hooks
├── layouts/        # 布局组件(Header、Sidebar)
├── pages/          # 页面组件(按路由划分)
│   ├── Home/
│   ├── User/
│   │   ├── List.tsx
│   │   ├── Detail.tsx
│   │   └── components/  # 页面私有组件
│   └── ...
├── router/         # 路由配置
├── store/          # 全局状态(Redux/Zustand)
├── styles/         # 全局样式、主题变量
├── types/          # 全局TS类型定义
├── utils/          # 工具函数(日期格式化、校验、存储)
└── main.tsx        # 入口

原则

  • 按功能/模块划分,不是按文件类型(不要把所有css放一个目录)。
  • 通用组件放components,页面独有组件放在页面目录下的components
  • API按业务模块拆分,不要一个api.ts放几百行。

三、API层:统一管理,妈妈再也不怕接口乱飞

很多项目直接在组件里写fetch('/api/user'),导致接口地址散落各处,改个域名要替换几十个文件。

正确姿势:封装API层。

// api/request.ts
import axios from 'axios';
const request = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000,
});
// 请求拦截器:加token、loading等
request.interceptors.request.use(config => {
  config.headers.Authorization = `Bearer ${getToken()}`;
  return config;
});
// 响应拦截器:统一错误处理、数据解构
request.interceptors.response.use(
  res => res.data,
  err => {
    if (err.response?.status === 401) {
      // 跳转登录
    }
    return Promise.reject(err);
  }
);
export default request;
// api/user.ts
import request from './request';
export const getUserInfo = (id: number) => request.get(`/user/${id}`);
export const updateUser = (data: User) => request.put('/user', data);

组件里只调用getUserInfo,不关心底层用axios还是fetch。

四、状态管理策略:别把所有东西都放全局

  • 组件内部状态useState
  • 跨组件但非全局ContextZustand 的小store。
  • 全局共享(用户信息、主题、权限):Redux/Pinia。
  • 服务器状态(缓存、请求状态):React Query / Vue Query(推荐),比手动管理loading、error、重试方便得多。

五、路由设计:懒加载 + 权限控制

  • 使用动态import()实现路由懒加载,减少首屏体积。
  • 封装一个AuthRoute组件,根据用户权限重定向或显示403。
// router/index.tsx
const routes = [
  {
    path: '/dashboard',
    component: lazy(() => import('@/pages/Dashboard')),
    meta: { requiresAuth: true, roles: ['admin'] }
  }
];
// 在Router组件里统一拦截

六、样式方案:别让CSS互相打架

  • CSS Modules:简单、无侵入、类型安全。
  • Tailwind CSS:快速开发,但团队需要适应。
  • CSS-in-JS(styled-components):动态样式方便,但运行时性能稍差。
  • BEM命名 + SCSS:传统但稳定。

推荐:CSS Modules + SCSS,或Tailwind + 普通CSS

七、错误处理与日志

  • 全局错误边界:React的ErrorBoundary捕获组件渲染错误。
  • API错误统一处理:在axios拦截器里做。
  • 开发环境用console,生产环境禁用或上报
if (import.meta.env.PROD) {
  console.log = () => {};
  console.warn = () => {};
}

八、代码规范与Git Hooks

  • ESLint:配置plugin:@typescript-eslint/recommended
  • Prettier:统一格式化。
  • Husky + lint-staged:提交前自动lint和格式化。
  • Commitlint:规范commit信息(如feat: xxxfix: xxx)。

九、环境配置与构建优化

  • 使用.env文件区分开发、测试、生产环境。
  • Vite配置别名@指向src
  • 生产构建:开启terser压缩、rollup-plugin-visualizer分析包体积、代码分割(splitChunks)。

十、总结:架构是不断演进的

没有完美的架构,只有适应当下团队的架构。但一个好的架构应该有这些特征:

  • 新人上手快:目录清晰,命名规范。
  • 可扩展:加新功能不破坏旧代码。
  • 可维护:修改一处不需要改十处。
  • 可测试:模块解耦,依赖注入。

别等到项目烂了才想重构。从第一天起,花点时间搭好架子,后面你会感谢自己。


如果你觉得今天的“架构课”够干货,点个赞让更多人看到。明天我们将开启一个新系列——性能优化实战,从首屏加载到运行时优化,让你的页面快到飞起。我们明天见!