从零搭一个现代化前端项目,我踩过的坑比你走的路还多

线上问题观察员
2026-01-03 11:18
阅读 701

去年双11大促前夜,我们团队临时接到产品需求:要为一个新业务线从零搭建一个高性能、可维护、支持快速迭代的前端项目。当时我正戴着耳机听着Lo-fi beats写代码,突然收到产品经理发来的“紧急”钉钉消息——“这个功能下周一上线,拜托了!”。我心里一万个MMP,但表面上还得回个“OK~ 😊”。

作为阿里P7前端工程师,经历过不止一次大促洗礼,我深知“从零开始”四个字背后藏着多少技术债和深夜加班的泪水。更别提我现在一边准备跳槽,一边刷LeetCode,还要应付这种突发需求,属实是地狱难度。

不过话说回来,这也是个机会。既然要重头来过,不如彻底现代化一把——告别老旧脚手架、混乱的目录结构、手动部署的原始操作。今天就借这篇文章,聊聊我是如何从零构建一个真正“现代化”的前端项目的,尤其聚焦在React生态下的技术选型与实战思考。


为什么这次不能再用 create-react-app?

很多同学第一反应肯定是 npx create-react-app my-app,简单粗暴,开箱即用。但如果你真的在大厂待过,就知道CRA(Create React App)在真实业务场景中有多“天真”。

  • 不支持微前端(我们内部系统全是微前端架构)
  • 构建速度慢得像蜗牛(双11期间改一行代码等5分钟?达咩)
  • 无法自定义Webpack配置(除非eject,但eject等于自杀)
  • 没有TypeScript深度集成(现在谁还敢不用TS?)

所以,我直接pass了CRA。取而代之的是 Vite + React + TypeScript 的组合。Vite的HMR(热更新)快到离谱,本地开发秒级启动,改完代码几乎无感知刷新。上周五晚上我改了个组件样式,保存后浏览器还没反应过来我已经切到另一个tab了——这就是生产力!

当然,也有人推荐 Next.js。确实,Next.js在SSR、SEO、路由管理上很香,但我们这个项目是纯后台管理系统,不需要服务端渲染,反而会引入不必要的Node.js依赖和部署复杂度。而且我们团队对K8s和云原生比较熟,静态资源直接扔OSS + CDN就行,根本不需要Node中间层。

方案 启动速度 构建速度 微前端友好 自定义能力 适用场景
CRA 弱(需eject) 快速原型、学习
Vite + React ⚡️极快 ⚡️快 好(配合Module Federation) 现代化SPA、后台系统
0
Next.js 一般 内容型网站、需要SSR

最终,我们选择了 Vite 作为构建工具,理由很朴素:快、轻、灵活。


目录结构:别再把所有东西塞进 src 了!

很多项目 src 下面堆着 components、utils、pages、hooks、assets……看起来整齐,实则混乱。一旦项目超过100个文件,找东西全靠全局搜索。

我参考了阿里内部的前端工程规范,采用 分层 + 领域驱动 的结构:

src/
├── app/               # 应用入口 & 全局状态
├── features/          # 业务功能模块(按产品功能划分)
│   ├── order/         # 订单模块
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── services/
│   │   └── index.tsx
│   └── user/
├── shared/            # 跨模块共享代码
│   ├── ui/            # 通用UI组件(Button, Modal等)
│   ├── lib/           # 工具函数、第三方封装
│   └── types/         # 全局TS类型
├── config/            # 环境配置、API地址
└── main.tsx

这样做的好处是:高内聚、低耦合。每个 feature 模块自包含,产品经理说“砍掉订单模块”,我直接删整个 order 文件夹,连Git记录都干净。

而且,这种结构天然支持 微前端拆分。未来如果要把订单模块独立成子应用,只需加个 expose 配置就行。


状态管理:别再无脑上 Redux 了!

坦白讲,Redux 在2024年已经不是默认选项了。我们这个项目交互不算复杂,主要是表单、表格、弹窗,完全没必要引入 Redux + Toolkit + Thunk + Saga 这套重型装备。

我试了三种方案:

  1. useState + useContext:简单场景够用,但跨层级传递还是麻烦。
  2. Zustand:轻量、API简洁、支持持久化,写起来像Vue的Pinia。
  3. Jotai:基于原子模型,适合细粒度状态,但学习曲线略陡。

最终选了 Zustand。为什么?因为它真的省心。看这段代码:

// store/orderStore.ts
import { create } from 'zustand';

interface OrderState {
  orders: Order[];
  loading: boolean;
  fetchOrders: () => Promise<void>;
}

export const useOrderStore = create<OrderState>((set, get) => ({
  orders: [],
  loading: false,
  fetchOrders: async () => {
    set({ loading: true });
    const data = await api.getOrders();
    set({ orders: data, loading: false });
  }
}));

没有 Provider,没有 action type,没有 reducer switch,直接在组件里 const { orders, fetchOrders } = useOrderStore() 就能用。测试也简单,因为 store 是纯函数。

而且 Zustand 支持 middleware,比如加个 logger 或 persist(本地缓存),几行代码搞定。双11期间我们遇到一个诡异的Bug:用户刷新后购物车清空。后来发现是没做持久化,加了个 persist middleware,问题秒解。


UI 组件库:Ant Design 还是自己造轮子?

作为阿里人,第一反应肯定是 Ant Design。但说实话,A ntd 的体积太大了,光一个 Button 就带了一堆你用不到的逻辑。而且样式定制困难,想改个 primary color 都得翻文档半小时。

这次我决定 自建轻量UI库,只封装真正需要的组件:

  • Button:支持 loading、size、type
  • Table:虚拟滚动 + 分页 + 排序
  • Modal:支持拖拽、ESC关闭
  • Form:配合 Zod 做校验

核心原则:够用就好,不求大而全。每个组件都用 Storybook 写了 demo 和测试用例,确保不会半夜被测试小姐姐@。

顺便吐槽一句:产品经理总想加“动画效果”,上次非要给表格加 fade-in,我说“亲,性能压测过吗?”,他立马闭嘴了。


构建与部署:拥抱云原生

既然我对 K8s 比较熟,那部署肯定不能还是 npm run build && scp dist root@server 这种原始操作。

我们的 CI/CD 流程:

  1. Git Push 到 main 分支
  2. GitLab CI 触发 Pipeline
  3. 构建 Docker 镜像(多阶段构建,base 镜像只有 20MB)
  4. 推送到私有 Harbor 仓库
  5. ArgoCD 自动同步到 K8s 集群
  6. Ingress 暴露服务,绑定 CDN

关键配置片段:

# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

线上环境跑在阿里云 ACK(K8s 托管版),配合 SLB + OSS 静态资源加速,首屏加载压到了 800ms 以内。双11当天峰值 QPS 5w+,稳如老狗。


性能优化:别让用户体验掉链子

现代化项目不能只跑起来就行,性能就是产品力

我们做了几件事:

  • 代码分割:路由级 + 组件级动态 import
  • 图片懒加载:用 loading="lazy" + Intersection Observer
  • 字体优化:本地托管 + font-display: swap
  • 缓存策略:immutable + contenthash,长期缓存
  • 监控上报:接入阿里内部前端监控平台(类似 Sentry)

最骚的操作是:把非关键 CSS 内联到 HTML,关键路径 JS 提前 prefetch。结果 Lighthouse 分数从 60 飙到 92。


最后:技术选型的本质是权衡

写到这里,耳机里的音乐刚好切到《Weightless》——据说是全球最放松的歌。而我也终于松了口气。

从零构建一个现代化前端项目,没有银弹,只有权衡。React 是我们的选择,但更重要的是围绕它搭建一套适合团队、产品、业务节奏的工程体系。

现在这个项目已经稳定运行半年,支撑了三个产品线的需求迭代。上周我拿它当跳槽面试的谈资,还拿到了不错的 offer。果然,能落地的技术方案,才是最好的简历

如果你也在从零开始,别急着抄作业。先问自己三个问题:

  1. 产品目标是什么?(To B 还是 To C?需要 SEO 吗?)
  2. 团队技术栈如何?(新人能不能快速上手?)
  3. 未来半年会怎么变?(会不会拆微前端?要不要国际化?)

想清楚这些,你的“现代化”才不会变成“过度设计”。

好了,不说了,LeetCode 第328题还在等着我。下次双11,希望我能在家躺着,而不是在工位debug。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝