项目做了一半想重写?这套前端架构让你少走3年弯路
你是不是经历过:项目写到一半,发现目录乱成毛线,组件互相依赖,改一个地方崩十个地方。想重写?老板说“没时间”。不重写?每天加班改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.tsimportaxiosfrom'axios';constrequest=axios.create({baseURL:import.meta.env.VITE_API_BASE_URL,timeout:10000,});// 请求拦截器:加token、loading等request.interceptors.request.use(config=>{config.headers.Authorization=`Bearer${getToken()}`;returnconfig;});// 响应拦截器:统一错误处理、数据解构request.interceptors.response.use(res=>res.data,err=>{if(err.response?.status===401){// 跳转登录}returnPromise.reject(err);});exportdefaultrequest;// api/user.tsimportrequestfrom'./request';exportconstgetUserInfo=(id:number)=>request.get(`/user/${id}`);exportconstupdateUser=(data:User)=>request.put('/user',data);组件里只调用getUserInfo,不关心底层用axios还是fetch。
四、状态管理策略:别把所有东西都放全局
- 组件内部状态:
useState。 - 跨组件但非全局:
Context或Zustand的小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: xxx、fix: xxx)。
九、环境配置与构建优化
- 使用
.env文件区分开发、测试、生产环境。 - Vite配置别名
@指向src。 - 生产构建:开启
terser压缩、rollup-plugin-visualizer分析包体积、代码分割(splitChunks)。
十、总结:架构是不断演进的
没有完美的架构,只有适应当下团队的架构。但一个好的架构应该有这些特征:
- 新人上手快:目录清晰,命名规范。
- 可扩展:加新功能不破坏旧代码。
- 可维护:修改一处不需要改十处。
- 可测试:模块解耦,依赖注入。
别等到项目烂了才想重构。从第一天起,花点时间搭好架子,后面你会感谢自己。
如果你觉得今天的“架构课”够干货,点个赞让更多人看到。明天我们将开启一个新系列——性能优化实战,从首屏加载到运行时优化,让你的页面快到飞起。我们明天见!
