从零搭起一个能扛住流量的前端项目,我踩过的坑比你写的代码还多

胡勇
2025-12-23 00:35
阅读 763

凌晨两点,咖啡凉了第三杯。屏幕右下角 Copilot 的小图标还在默默闪烁——这玩意儿我已经付费快两年了,说真的,它救过我至少十次 deadline。最近一边准备跳槽刷 LeetCode,一边还得给新业务搭前端架子,产品经理上周五下午甩过来一句“下周上线 MVP”,差点让我当场表演原地去世。

但没办法,干就完了。这次要从零开始搞一个现代化前端项目,目标是:上线不崩、体验不卡、维护不哭。下面这些经验,全是我在深夜 debug、被线上报警吵醒、以及和运维兄弟对骂(友好交流)后总结出来的最佳实践。


别一上来就 npx create-react-app

我知道很多人(包括一年前的我)觉得脚手架开箱即用,省事。但现实是:默认配置在真实业务场景里基本等于裸奔

我们这次选的是 Vite + TypeScript + React 18 + Tailwind CSS 技术栈。理由很现实:

  • Vite 冷启动快:本地开发秒开,再也不用等 webpack 转译等到怀疑人生。
  • TypeScript 强约束:团队协作时,类型就是最好的文档,避免“这个参数到底传不传?”的灵魂拷问。
  • Tailwind:不用再纠结 class 名叫 btn-primary 还是 primary-button,设计系统直接写进配置,UI 一致性拉满。

初始化命令其实就一行:

npm create vite@latest my-frontend -- --template react-ts
cd my-frontend
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

但关键在后续的工程化治理——这才是区分“玩具项目”和“能运营的项目”的分水岭。


项目结构:别让文件乱成“面条”

见过太多项目根目录堆了 20 个 .js 文件,utils/ 里塞了网络请求、日期格式化、加密解密……最后新人接手直接懵逼。

我们的结构长这样:

src/
├── app/               # 应用入口与路由
├── features/          # 按业务域划分的功能模块(核心!)
│   ├── user-profile/
│   └── checkout/
├── shared/            # 跨模块复用的东西
│   ├── components/    # 公共组件(带 storybook)
│   ├── hooks/         # 自定义 hook
│   └── lib/           # 工具函数、第三方封装
├── entities/          # 领域模型(比如 User, Product)
└── config/            # 环境变量、API 配置

重点来了features/ 是按业务能力拆分,不是按页面。比如 checkout 里包含所有结账相关的组件、逻辑、测试。这样未来做微前端或独立部署都方便。


GitHub 不只是代码仓库,更是运营中枢

很多团队把 GitHub 当纯代码托管,太浪费了。我们把它变成了项目运营的神经中枢

  1. PR 模板强制规范:要求写清楚“改了啥”、“影响范围”、“如何测试”。不然我就得半夜爬起来看你的 commit message 猜意图。
  2. 自动化流水线
    • Push 到 main → 自动构建 + 部署到 staging
    • 合并 PR 前必须通过:单元测试 + ESLint + Prettier + Lighthouse 评分 > 90
  3. Issue 即需求池:产品经理的需求直接建 Issue,打上 priority: high 标签,我们按标签排期。再也不用翻 50 条企业微信消息找需求。

Copilot 在这里也帮了大忙——写 CI 配置文件时,它能根据我注释“需要部署到 AWS S3 并刷新 CloudFront”,自动生成完整的 .github/workflows/deploy.yml。虽然要改两处,但比查文档快多了。


资源加载:性能不是玄学,是数学

用户不会等你 3 秒才看到首页。我们做了这几件事:

动态导入 + 代码分割

// 路由级懒加载
const UserProfile = lazy(() => import('@/features/user-profile'));

// 组件级条件加载(比如只在移动端加载地图)
{isMobile && <Suspense fallback={<Spinner />}>
  <MapComponent />
</Suspense>}

静态资源优化

  • 图片全部转 WebP,用 <picture> 兜底兼容
  • 字体预加载 + font-display: swap
  • 关键 CSS 内联,非关键异步加载

缓存策略

资源类型 Cache-Control
HTML no-cache
JS/CSS (hashed) max-age=31536000, immutable
图片 max-age=86400

上线后 Lighthouse 性能分从 58 直接飙到 96。产品经理第一次没在群里@我说“页面怎么这么卡”。


代码人生:别让技术债压垮你

我见过太多项目初期“先跑起来再说”,结果三个月后没人敢动核心模块——因为一改就崩。

我们的原则是:可维护性优先于炫技

  • 自定义 Hook 封装副作用:比如 useApi 统一处理 loading/error/retry,业务组件里只关心数据流。
  • 组件 Storybook 可视化:每个公共组件都有 demo 和 props 说明,新人直接看故事书就能用,不用跑整个项目。
  • 监控埋点标准化:用统一的 trackEvent('button_click', { location: 'header' }),而不是东一个 ga() 西一个 logClick()

最爽的是,上周修复一个支付按钮 bug,因为有完善的单元测试(Jest + React Testing Library),我改完直接 push,CI 过了就 merge,连真机都没测——信任你的测试,就像信任你的 Copilot(虽然它偶尔也会胡说八道,比如建议我用 var 而不是 const,笑死)。


分布式思维:前端也要考虑“失败”

你以为前端只是渲染?错。在高并发场景下,前端是第一道防线。

  • 请求去重:用户狂点提交按钮?用 useDebounce 或请求 ID 去重。
  • 优雅降级:如果推荐模块 API 挂了,直接隐藏,而不是白屏。
  • 错误边界兜底:React Error Boundary 捕获子组件异常,显示友好提示,而不是整个 App crash。

去年双11,我们首页某个第三方广告脚本挂了,因为用了错误边界,主流程完全不受影响。运维兄弟在 Slack 里给我发了个 🍻 —— 这种时刻,感觉代码人生值了。


最后几句大实话

从零搭项目,技术选型只是 20%,剩下 80% 是流程、规范和人的协作。GitHub 是你的运营平台,资源加载是你的用户体验底线,而代码人生,是你每天面对键盘时的选择——是糊弄过去,还是留下值得骄傲的作品?

我现在边刷题边优化这个项目,说不定下家公司面试时,就能指着 GitHub 仓库说:“看,这是我一个人搞起来的,能扛住日活 10w+。”

对了,如果你也在深夜写代码,记得打开 Copilot。它可能写不出完美代码,但至少能让你少喝一杯咖啡——毕竟,程序员的时间,比星巴克贵多了。

评论 0

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