从零搭起一个能扛住流量的前端项目,我踩过的坑比你写的代码还多
凌晨两点,咖啡凉了第三杯。屏幕右下角 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 当纯代码托管,太浪费了。我们把它变成了项目运营的神经中枢:
- PR 模板强制规范:要求写清楚“改了啥”、“影响范围”、“如何测试”。不然我就得半夜爬起来看你的 commit message 猜意图。
- 自动化流水线:
- Push 到
main→ 自动构建 + 部署到 staging - 合并 PR 前必须通过:单元测试 + ESLint + Prettier + Lighthouse 评分 > 90
- Push 到
- 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