从零开始构建一个现代化前端项目:一个老广程序员的血泪总结

后端漫游指南
2026-01-14 03:36
阅读 1514

文 / 阿强,35岁,广州西关老城区土著,白天写 Java,晚上调 React,周末还得陪老婆逛上下九。


去年十月的一个周五晚上,我瘫在荔湾老屋的旧沙发上,左手冰镇王老吉,右手 MacBook Pro,屏幕上是第 17 次 npm install 失败的报错。窗外是恩宁路深夜的车流声,屋里是我老婆在厨房洗碗时哼着《荔枝颂》。那一刻,我真的想把电脑砸了——不是因为 bug,而是因为我搞不懂,为什么一个“简单”的新项目,要用这么多破玩意儿。

事情得从头说起。

我们公司接了个新活,给一家本地茶饮连锁做一套门店管理系统。后端用 Spring Boot(这我熟,写了快十年 Java,闭着眼都能搭个三层架构),但前端这次老板点名要“现代化”——React + TypeScript + Vite + Tailwind + Redux Toolkit,还说“对标一线大厂”。我一听就头皮发麻。我上一次正经写 React 还是 2019 年,那时候 Hooks 刚出,我还觉得 class component 更香。

HR 老李拍着我肩膀说:“阿强啊,你技术底子好,又是老广,稳重!月薪从 15k 涨到 22k,干不干?”
我说:“干!但能不能给我两周时间先搭环境?”
他说:“行,下周三 demo 给客户看。”
我当时差点一口老豆沙包喷他脸上。


开局就是地狱难度

周一早上 8 点,我坐在公司工位(天河某共享办公空间,月租 3500,离家地铁一小时),新建了一个项目文件夹,名字叫 tea-shop-admin-v2。然后就开始了“依赖地狱”。

  • create-react-app?太老了,社区都说别用了。
  • Vite?听说快,但配置一堆插件,我连 vite.config.tsresolve.alias 是啥都要查文档。
  • TypeScript?我只会写 interface 和 type,泛型一复杂就懵。
  • Tailwind?以前用 Bootstrap 写页面,现在要记 flex justify-between items-center 这种咒语?
  • 还有 ESLint、Prettier、Husky、lint-staged……装完一整套,项目还没写一行业务代码,node_modules 已经 800MB。

最搞笑的是,我照着网上教程配完,跑起来发现热更新失效。查了一下午,原来是 Webpack 和 Vite 的缓存冲突——但我根本没装 Webpack 啊!后来才发现是某个依赖偷偷带进来的。这种“隐式依赖”的坑,只有踩过才知道有多疼。

那几天晚上回家,老婆问我:“最近怎么总皱眉头?”
我说:“我在跟 npm 打架。”
她说:“打不过就请它喝茶咯。”
我苦笑:npm 喝的是我的肝。


后端反哺前端:Spring Boot 救了我一命

转机出现在第三天。我突然意识到:我是个全栈,不是纯前端!

既然后端用 Spring Boot,那为什么不把 API 设计清楚,再让前端消费?于是我花了半天时间,用 Swagger 写完了所有接口文档:

@RestController
@RequestMapping("/api/v1/stores")
public class StoreController {
    
    @GetMapping
    public ResponseEntity<List<StoreDTO>> listStores() {
        // ...
    }
    
    @PostMapping
    public ResponseEntity<StoreDTO> createStore(@Valid @RequestBody CreateStoreRequest request) {
        // ...
    }
}

关键是,我用 Lombok + MapStruct 把 DTO 转换做得贼干净,返回的 JSON 结构清晰、命名规范(camelCase)、错误码统一。前端同学(其实就是我自己)拿到这个 API,直接可以用 axios 封装:

// api/store.ts
export const fetchStores = () => 
  axios.get<Store[]>('/api/v1/stores').then(res => res.data);

那一刻我悟了:现代化前端不是堆砌工具链,而是建立清晰的契约。

Spring Boot 的强类型 + OpenAPI 规范,让前后端协作变得像两个讲粤语的老友——不用多解释,一句“得啦”就懂。


开发心得:少即是多,约定大于配置

经过两周的折腾(包括三次重装 node_modules、两次格式化硬盘),我终于跑通了第一个页面:门店列表页。虽然丑得像 2003 年的网页,但数据能动,交互能跑。

我总结了几条血泪教训,分享给还在泥潭里的兄弟:

1. 别一上来就搞微前端、Monorepo

很多教程吹得天花乱坠,但对小团队来说,一个 vite + react + ts 脚手架足够。我见过太多人花三天配 Nx,结果业务逻辑一行没写。

2. 状态管理别过度设计

Redux Toolkit 确实比原生 Redux 好用,但如果你的项目只有三个页面、两个全局状态,直接用 React Context + useReducer 就够了。别为了“技术先进”而引入复杂度。

3. 样式方案选一个,别混用

Tailwind 很香,但千万别一边写 className="p-4",一边又 import 一个 styles.module.css。我上周就因为这个导致样式优先级混乱,调试到凌晨两点。

4. 后端要主动提供“前端友好”的 API

比如分页,别返回 { data: [], total: 100 },而是 { content: [], pageable: { page: 0, size: 10 }, totalElements: 100 } —— 这种结构前端处理起来更直观。Spring Data JPA 默认的分页结构其实就很合理,别自己魔改。

5. 自动化要早做,但别贪多

我最后只加了两样:

  • 提交前自动 lint(Husky + lint-staged)
  • CI 跑单元测试(GitHub Actions)
    其他什么自动化部署、镜像构建,等项目稳定了再说。前期搞太多,纯属内耗。

真实世界的妥协:技术 vs 现实

上个月 demo 顺利通过,客户满意,老板开心。但我知道,这个项目还有很多“脏东西”:

  • 有些组件重复写了三次,因为赶时间没抽离;
  • 错误边界没加,一旦 API 返回异常,整个页面白屏;
  • 测试覆盖率不到 20%,全是 console.log 调试。

但现实是:我们不是在写开源项目,而是在交付能赚钱的软件。 我老婆说得对:“系统能用,老板肯给钱,你就能继续供楼。”

现在的我,已经能在 React 里写出还算体面的代码了。虽然看到 useEffect 里套 async/await 还会皱眉,但至少不会再因为 Cannot read property 'map' of undefined 而摔键盘。


最后一点思考:35 岁程序员还能折腾吗?

很多人说,35 岁就该转管理、带团队,别再碰代码。但我觉得,只要手还能敲键盘,脑子还能 debug,就别轻易放弃一线。

我不是天才,学新东西比 25 岁的实习生慢。但我的优势是什么?是知道哪些坑没必要踩,哪些轮子不用造。Spring Boot 的约定优于配置,React 的组合优于继承——这些理念,其实和老广的生活哲学很像:务实、高效、不花假。

上周五晚上,我又在阳台喝王老吉。这次屏幕上跑的是新版本的门店系统,界面清爽,交互流畅。老婆走过来问:“这次搞定啦?”
我说:“搞掂晒啦。”
她笑:“咁今晚得闲陪我去吃云吞面未?”
我说:“得!”


给你的建议

如果你也在从零搭建一个现代化前端项目,别被那些“最佳实践”吓住。记住:

  • 先跑起来,再优化。能显示数据的页面,比完美的架构图更有价值。
  • 善用你的后端经验。Java 程序员写前端,最大的优势不是会 JS,而是理解系统、数据、契约。
  • 接受不完美。没有哪个项目是从第一天就“现代化”的,都是边做边进化。

技术会变,框架会换,但解决问题的能力不会过时。35 岁的我,依然相信:写代码,是件快乐的事。

哪怕是在广州 35 度的夏天,开着 26 度的空调,对着满屏的 red underline,心里骂一句“顶你个肺”,然后继续敲下去。

因为下一行代码,可能就是解药。


本文写于 2024 年 6 月,广州西关老屋,窗外正落着龙舟水。
如果你也在这条路上挣扎,不妨留言聊聊——或者,请我饮杯凉茶。

评论 0

最热最新
暂无评论
后端漫游指南Lv.1
0
影响力
0
文章
0
粉丝