从零开始构建一个现代化前端项目:一个考公程序员的深夜实战手记
作者:阿哲,深圳南山某互联网公司“资深”前端(其实才3年经验),白天写代码,晚上刷行测,梦想上岸吃皇粮。
去年十月的一个周五晚上,我瘫在出租屋的宜家二手沙发上,手里攥着半瓶冰啤酒,眼睛死死盯着屏幕上那个空白的 VS Code 窗口。窗外是深圳湾的霓虹,屋里是泡面味混着键盘油光——没错,我又双叒叕接了个私活。
起因很简单:老婆(对,已婚打工人)的表弟要开一家宠物美容店,想做个官网+预约系统,预算不多,但语气诚恳:“姐夫,你不是大厂程序员吗?随便搞搞就行!”
我心想:随便搞搞?呵,前端哪有“随便”这俩字?
更魔幻的是,我一边敲代码,一边还在手机上刷着粉笔APP的常识判断题。左手npm install,右手“下列不属于行政强制措施的是?”——这就是当代考公程序员的真实生活。
起手式:别一上来就“现代化”
很多人一听“现代化前端项目”,立马想到 Vite + React 18 + TypeScript + Tailwind + Zustand + …… 一整套全家桶直接糊脸上。但现实是:资源有限,时间紧迫,需求模糊。
那天晚上,我深吸一口气,先问了三个灵魂问题:
后端用啥?
表弟说:“听朋友说 Springboot 很火,能用不?”
我差点笑出声——Springboot 是 Java 后端框架啊兄弟!但转念一想,行吧,至少他没说“能不能用 Python 做个 iOS App”。预算多少?
“五千块包干,含部署和三个月维护。”
我沉默了三秒,默默打开了 Figma 免费版。上线时间?
“最好下周三前,我要拿去申请营业执照。”
……好家伙,这是要我七天造火箭?
于是,我决定:不炫技,只解决问题。现代化不是堆技术,而是用合适的工具,在有限资源下跑通闭环。
技术选型:务实主义者的妥协艺术
我列了个极简清单:
- 前端框架:React(团队熟悉,生态稳)
- 构建工具:Vite(快,省时间)
- UI 库:Tailwind CSS(不用写 CSS,救命稻草)
- 状态管理:Zustand(轻量,够用)
- 请求库:axios(老熟人了)
- 部署:Vercel(免费、一键、自动 HTTPS)
重点来了:前后端分离。后端用 Springboot 提供 RESTful API,前端纯静态部署。这样我和表弟可以并行开发,互不干扰——毕竟他连 Postman 都不会装。
我甚至没用 TypeScript。不是不爱,是真没时间配类型。考公复习都排到凌晨一点了,哪还有精力写 interface?JS + JSDoc 够用了,心里默念:“先跑起来,再优化。”
搭架子:五分钟搞定基础结构
周六早上八点,我顶着黑眼圈打开电脑,用 Vite 一行命令初始化项目:
npm create vite@latest pet-spa -- --template react
进目录,装依赖,删掉所有示例文件,保留 App.jsx 和 main.jsx。然后:
- 装 Tailwind:按官网指南三步走,5 分钟搞定。
- 装 axios,建
api/目录,写个instance.js配 baseURL。 - 装 zustand,建
store/useBookingStore.js,塞个假数据进去。 - 写个简单的路由(用 React Router DOM v6),首页、服务页、预约页、后台登录页。
整个过程不到两小时。为什么这么快?因为不纠结。按钮颜色?用 Tailwind 默认蓝。字体?系统默认。动画?没有。SEO?后期再说。
中午吃饭时,老婆看我笑得诡异,问:“搞定啦?”
我说:“骨架搭好了,接下来就是填肉——和改需求。”
果然,下午表弟微信轰炸:“姐夫,能不能加个会员积分功能?”“首页能不能自动轮播宠物照片?”“用户注册要手机号验证码!”
我深吸一口气,回了个“OK”,心里默念:“需求如潮水,稳住别浪。”
联调 Springboot:跨语言的爱恨情仇
周日晚上,表弟发来 Springboot 后端地址。我打开 Swagger 文档一看,心凉半截:
- 接口命名风格不统一(有的
/user/getInfo,有的/booking-create) - 返回字段大小写混乱(
userNamevsuser_name) - 错误码全是 200,靠 body 里的
code字段判断
我忍住没骂人,默默写了几个 axios 拦截器:
// 请求拦截器:统一加 token
axios.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${(token)}`;
return config;
});
// 响应拦截器:统一处理错误
axios.interceptors.response.use(
response => {
if (response.data.code !== 200) {
toast.error(response.data.msg || '操作失败');
return Promise.reject(response.data);
}
return response.data.data; // 直接返回 data 层
},
error => {
toast.error('网络错误,请重试');
return Promise.reject(error);
}
);
还写了个 transformKeys 工具函数,把 snake_case 转成 camelCase,不然前端看着想吐。
最搞笑的是,表弟问我:“前端能直接调数据库吗?这样快一点。”
我回:“能,但你会被警察叔叔请去喝茶。”
他:“啊?为啥?”
我:“因为那是黑客行为,亲。”
资源焦虑:时间和金钱的双重夹击
说到资源,真的扎心。
我在南山科技园上班,月薪 22k(税前),房租 3500(合租次卧),每月固定支出近 8k。考公报班花了 6800,教材又花 500。接这个私活,纯粹是亲情价+练手。
但时间呢?工作日加班到九点,回家刷两套行测;周末两天,一天陪老婆,半天写代码。真正的“碎片化开发”。
有天凌晨一点,我还在调 Tailwind 的响应式断点,老婆推门进来:“又不睡?明天还要早起模考呢。”
我说:“这个 modal 在 iPad 上错位了,我再改五分钟。”
她叹口气:“你图啥?考公上岸不比这强?”
我愣住,没回答。其实我心里清楚:写代码是我目前唯一能掌控的事。行测分数忽高忽低,申论写得自己都看不下去,只有代码,跑通了就是跑通了,不会骗人。
转折:一次意外的技术分享
项目上线前夜,我在公司茶水间吐槽这事。隔壁组的后端大哥老李听见了,说:“你这不就是个标准 MPA(多页应用)场景?用 Astro 不香吗?”
我一愣:“Astro?那不是静态站点生成器?”
他喝了口枸杞茶:“对啊,你这又不需要复杂交互,首屏性能拉满,SEO 还好。Vercel + Astro,五分钟后部署。”
我当晚回去试了试,真香!首页加载从 2.1s 降到 0.4s。虽然最后没换(怕翻车),但这次聊天让我意识到:闭门造车不如开放交流。
后来我在公司内部做了个 15 分钟的技术分享,主题就叫《如何用最少资源交付一个能赚钱的前端项目》。没想到反响不错,HR 甚至问我:“要不要转岗做解决方案工程师?薪资可谈。”
我婉拒了。不是不想涨薪,而是——我的心已经不在“卷技术”上了。
反思:现代化 ≠ 高大上,而是“刚刚好”
现在回头看,这个项目技术含量不高,甚至有点“土”。但它教会我一件事:
现代化前端的核心,不是用了多少新框架,而是在约束条件下,做出最平衡的选择。
- 时间紧?那就砍掉非核心功能。
- 预算少?就用免费方案(Vercel, Supabase, Firebase)。
- 团队弱?就选最熟悉的工具,别追求“最佳实践”。
- 自己忙?就自动化一切(CI/CD、格式化、测试)。
更重要的是,技术只是手段,不是目的。表弟的店上周开业了,我去看了一眼——网站挂在收银台旁边的小平板上,顾客扫码就能预约。那一刻,我觉得值了。
写在最后:一个考公程序员的自白
我知道,很多人觉得“程序员考公”是退缩,是躺平。但我想说:不是所有人都想一辈子和 bug 打交道。
在深圳,35 岁危机像达摩克利斯之剑。我见过太多同事被优化后焦虑失眠,也见过考公上岸的朋友晒出稳定的公积金。我不是逃避,我只是在寻找一种更适合自己的生活节奏。
当然,代码我还会继续写。毕竟,技术分享的本质,是把踩过的坑变成别人的梯子。这篇文,也算是我留给前端社区的一点微小贡献。
至于未来?如果明年上岸了,我就把这套“极简前端搭建法”整理成开源模板,名字都想好了:civil-servant-starter ——献给所有在理想与现实之间挣扎的打工人。
(完)
P.S. 项目虽然简单,但完整源码我放 GitHub 了(搜 pet-spa-minimal),欢迎 star。如果你也在边工作边备考,评论区留个言,咱们抱团取暖。毕竟,在深圳这座城,能互相理解的人,不多了。

评论 0