项目名: 绿能充电
技术栈: React 19 + Vite 8 + Tailwind CSS v4 + Chart.js + React-Leaflet + Express + SQLite + Socket.IO
作者: 一个刚被产品经理气完的前端
大家好,我是一名前端开发者。最近接了一个叫「绿能充电」的项目——给充电站老板们做一个后台管理系统,能看桩、管订单、出报表、看地图。
老板说:“这个项目不大,你一个人搞定前端就行,后端我招了个刚毕业的小伙子。”我当时心想:完了,又要当爹又当妈了。
于是,在一个又一个深夜(其实主要是摸鱼时间),我对着屏幕做技术选型。今天就把我那些不理智、不客观、但真实好用的选型过程,原汁原味地分享出来。
如果看完你觉得“这也行?”,那说明你也是个实战派。
一、为什么是 React 19 而不是 Vue 3?
——因为 Vue 的模板语法,我看一眼就犯困
坦白说,Vue 3 的 Composition API 我也用过,写起来像在背唐诗。template 里塞一堆 v-if v-for v-model,还要记住 .sync 被干掉了、.native 也没了……我脑子真的不够用。
而 React 19 多直接啊:
{list.map(item => <div key={item.id}>{item.name}</div>)}
不就是 JS 吗?我会 JS 就会写 React。
更真实的原因有四个:
1. 我熟,省钱
我们团队就我一个前端,我 React 写了三年。选 Vue 等于我自己给自己挖坑,光重新熟悉 watch Effect 就得浪费两个下午。老板催得急,我没空学习。
2. 生态里全是“懒人包”
- 我要地图 →
react-leaflet - 我要图表 →
chart.js有 React 封装 - 我要实时通信 →
socket.io-client在 React 里用着顺手
Vue 的生态当然也有,但我懒得去翻“哪个库还活着”。React 生态更像万能的淘宝,要啥搜啥,基本都有。
3. TypeScript 写起来不卡
充电桩的数据结构乱七八糟:桩状态、订单金额、用户余额、设备编号……React + TS 我闭着眼写泛型。Vue 的 defineProps 虽然也支持 TS,但遇到复杂类型推导,编译器老是给我脸色看。
4. 老板画过饼:以后可能会做移动端 App
React Native 至少还能用用。Vue 的跨平台方案……咱就不提了,提就是痛。选 React 属于“给未来留个念想”,哪怕这个未来永远不会来。
吐槽一句:React 19 的 Compiler 和 Actions 我至今没用上,但版本号写高一点,面试官会觉得我紧跟潮流。
二、Vite 8 vs Webpack:我受够了“npm run dev 然后去泡杯咖啡”
以前用 Webpack 5 的时候,每次启动项目,我都要默念三遍“好事多磨”。因为等它编译完,我咖啡都凉了。
Vite 8 救了我的命:
- 冷启动速度:
npm run dev→ 眨眼功夫 → 页面出来了。实测“绿能充电”项目 300ms。 - 热更新体验: 改一行代码,保存,页面几乎“闪一下”就好了。不像 Webpack,改个 CSS 它都要“重新编译一次”,像极了早高峰的地铁。
- 配置简单到令人发指: 我要做的事:路径别名
@指向src、API 代理(避免跨域)、环境变量。Vite 配置文件就这么几行:
export default defineConfig({
resolve: { alias: { '@': '/src' } },
server: { proxy: { '/api': 'http://localhost:3000' } }
})
换成 Webpack?你得装七八个插件,写 50 行配置,还不一定能跑起来。
- 构建产物还更小了: Webpack 打包出来首屏资源 1.2MB,Vite + Rollup 打包出来 850KB。老板在 4G 网络下打开后台,夸我“优化得不错”,我心想:其实是 Vite 的功劳,跟我没啥关系。
吐槽一句:Vite 8 都出来了,我还在用 Vite 5,但对外统一说“我们用的最新版”——反正老板又看不懂。
三、Tailwind CSS v4:因为我实在想不出 CSS 类名了
我以前写 CSS 最痛苦的事就是起名字。.charging-station-list-wrapper 太啰嗦,.card-container 太普通,.left-column-inner-box 是什么鬼?后来用了 Tailwind,世界清静了。
直接写:
<div className="flex justify-between p-4 bg-white rounded-lg shadow">
充电桩数据
</div>
不用切文件,不用想名字,不用怕样式冲突。爽不爽?爽!
Tailwind v4 的三个“真香”时刻:
1. Rust 重写,构建飞快
以前改 tailwind.config.js 要等好几秒,现在几乎是瞬间。
2. 自定义主题不用写 JS 配置
我们品牌色是“绿能绿”(#00E5A0),直接写在 CSS 里:
@theme {
--color-brand: #00E5A0;
}
然后全站用 bg-brand text-brand,不用折腾 config 文件。
3. 暗黑模式简单到发指
老板说“要支持深色主题”,我用 Tailwind 的 dark: 前缀,半小时搞定。要是用 CSS Variables,我得先写一堆 --bg-primary,再写 JS 切换 class……想想就头大。
当然也有槽点:JSX 里类名一长串,看起来像火车。但反正不是我一个人看,后端同事也不看前端代码,怕啥?
四、SQLite 而不是 MySQL?——因为我后端同事只会 SQLite
真的,不骗你。后端刚毕业的小伙子,简历上写着“熟悉 SQLite”。
我问他:“MySQL 你会吗?”
他说:“会一点,但安装配置好麻烦……”
我一想:这个项目初期就几个站长用,并发不超过 10 个人,SQLite 完全够。
SQLite 的好处(对于懒人来说):
1. 零运维
不用装 MySQL 服务,不用设置 root 密码,不用开端口,不用做主从复制。
charging.db 就是一个文件,备份直接复制它。
2. 性能出乎意料地好
我们的业务就是查订单、统计收益、更新桩状态。SQLite 嵌入 Node 进程,省去了网络 IO,查询 20ms 内返回。MySQL 反而要多一层网络开销。
3. 数据量真的不大
一个中型充电站 20 个桩,每桩每天充 30 次,一天 600 条订单,一年不到 22 万条。SQLite 处理几千万条都没问题,我们这点数据是“洒洒水”。
那什么时候换 MySQL?
等用户量到 1 万再说。到时候一天就能迁移过去,现在提前上 MySQL 就是过度设计。
吐槽一句:SQLite 不支持高并发写,但我们最高的并发场景是“老板和三个站长同时点刷新”——这叫高并发吗?这叫“高摸鱼”。
五、整体架构:能跑就行,不高大上
“绿能充电”的架构图我画了十分钟,其实就是:
为什么这么简单?
- 前后端分离: 前端可以部署在 Vercel(免费),后端扔到一个 2 核 4G 的云服务器上,成本极低。
- 实时数据用 Socket.IO: 充电桩状态变化(充电中、故障、空闲)要实时推给前端。用轮询太蠢,WebSocket 原生 API 太难用,Socket.IO 一把梭。
- 地图用 React-Leaflet: 免费,够用。不用 Google Maps 是因为要钱,老板听到“钱”字会杀人。
- 图表用 Chart.js: 轻量,文档简单。ECharts 更好,但打包体积大一倍,没必要。
核心原则: 提前优化是万恶之源。
能用 SQLite 就不用 MySQL,能用 Vite 就不用 Webpack,能用一个前端绝不用两个。
结尾:技术选型就像相亲,合适比优秀更重要
“绿能充电”上线一个月了,没出过大问题。老板很开心,后端也不累,我更爽——每天准点下班,偶尔还能摸摸鱼。
如果你也是一个人扛项目、团队小、预算少、时间紧,那这套技术栈(React + Vite + Tailwind + SQLite)完全可以复制粘贴。
等哪天项目火了(大概率不会),再重构也来得及。
点赞过 200,我立刻更新下一篇。
点赞不过?那我……求求你们了,点一下吧,我写稿真的很累。
评论区开放吵架:你为啥不用 Vue?Webpack 还能再战?SQLite 上生产就是作死?——你说得对,但我下次还敢。