放弃React+Node.js后,我发现了更简单的全栈方案
最近帮朋友做了一个小项目,用来记录学院的桶装水配送情况。本来以为是个很简单的需求,没想到做出来之后,发现这个小系统还挺有意思的。
需求很简单
朋友在学院负责桶装水配送,每天要记录:
- 送了多少桶普通水
- 送了多少桶农夫山泉
- 拿走了多少个空桶
- 还剩多少个空桶
之前用纸质记录,容易丢失,也不方便查询历史数据。他希望有个简单的网页系统,能在手机上操作,数据不会丢失。
项目截图




技术选择
这种小系统,最重要的是简单可靠。我选择了 Cloudflare Workers + KV 存储的方案。
为什么选择 Cloudflare Workers?
- 零服务器维护:不用买服务器,不用配置环境,代码部署后就能跑
- 全球分发:Cloudflare 的边缘网络覆盖全球,访问速度快
- 成本极低:免费额度对小项目完全够用
- 开发简单:就是写 JavaScript,没有复杂的框架
为什么用 KV 存储?
Cloudflare KV 是一个分布式键值存储,特点是:
- 全球同步
- 读取速度极快
- 写入有一定延迟
对于送水记录这种场景,数据量小,读多写少,KV 存储完全够用。
架构设计
整个系统核心文件就是一个 JavaScript 文件,包含:
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const path = url.pathname;
// 路由处理
if (path === '/') {
return new Response(getHTML(), {
headers: { 'Content-Type': 'text/html' }
});
}
if (path === '/api/delivery' && request.method === 'POST') {
return await handleDelivery(request, env);
}
// 其他 API 路由...
}
};
前后端代码都在一个文件里,HTML、CSS、JavaScript 全部内联。这样做的好处是部署简单,坏处是代码有点长(1400多行)。
核心功能实现
1. 数据存储
每条送水记录存储为一个 KV 键值对:
const record = {
date: '2024-01-15',
timestamp: '2024-01-15T10:30:00.000Z',
normalWater: 5,
nongfuWater: 3,
totalDelivered: 8,
emptyBucketsTaken: 6,
remainingEmptyBuckets: 12
};
const recordKey = `delivery_${timestamp.replace(/[:.]/g, '_')}`;
await env.WATER_KV.put(recordKey, JSON.stringify(record));
2. 空桶计算
这是系统的核心逻辑:
// 获取当前空桶数量
const currentStatus = await env.WATER_KV.get('current_status');
let status = currentStatus ? JSON.parse(currentStatus) : { emptyBuckets: 0 };
// 计算新的空桶数量
const deliveredBuckets = normalWater + nongfuWater;
status.emptyBuckets = status.emptyBuckets + deliveredBuckets - emptyBuckets;
// 防止空桶数量为负
if (status.emptyBuckets < 0) {
return new Response(JSON.stringify({
error: `空桶数量不足,当前只有 ${status.emptyBuckets + emptyBuckets} 个空桶`
}), { status: 400 });
}
3. 用户认证
简单的用户名密码验证:
if (username === env.USERNAME && password === env.PASSWORD) {
return new Response(JSON.stringify({ success: true }));
}
用户名和密码存储在环境变量中,登录状态保存在浏览器的 localStorage。
前端设计
界面采用了现代化的设计风格:
- 渐变色背景
- 毛玻璃效果
- 响应式布局
- 流畅的动画过渡
关键是要在手机上好用,所以做了很多移动端优化:
@media (max-width: 768px) {
.container {
margin: 10px;
border-radius: 8px;
}
.header h1 {
font-size: 1.8em;
}
.form-section {
padding: 20px;
}
}
部署过程
部署非常简单:
- 安装 Wrangler CLI
- 创建 KV 命名空间
- 配置环境变量
- 一键部署
npm install -g wrangler
wrangler kv:namespace create "WATER_KV"
wrangler publish
部署完成后,就得到一个 https://xxx.workers.dev 的地址,全球都能访问。
使用体验
系统上线后,朋友反馈很好:
- 操作简单:打开网页,输入数字,点击提交
- 响应快速:得益于 Cloudflare 的边缘网络
- 数据可靠:再也不用担心记录丢失
- 查询方便:可以按日期筛选历史记录
- 导出功能:支持导出 Excel 格式
成本分析
Cloudflare Workers 的免费额度:
- 每天 100,000 次请求
- KV 存储 1GB 空间
- 每天 1,000 次 KV 写入
- 每天 100,000 次 KV 读取
对于这个小系统来说,免费额度完全够用。即使超出免费额度,付费价格也很便宜。
技术思考
简单就是美
很多时候,我们习惯用复杂的技术栈:React + Node.js + MySQL + Redis + Nginx...但对于简单的需求,这些可能都是过度设计。
一个 JavaScript 文件,解决了前端、后端、数据库、部署的所有问题。虽然代码组织不够优雅,但胜在简单可靠。
边缘计算的价值
Cloudflare Workers 运行在边缘节点上,用户访问时会自动选择最近的节点。这种架构对于全球化应用特别有价值。
无服务器的优势
传统的服务器部署,需要考虑:
- 服务器配置和维护
- 负载均衡
- 数据库备份
- 监控告警
- 安全更新
而 Serverless 架构把这些都交给了云服务商,开发者只需要关注业务逻辑。
可能的改进
如果要继续完善这个系统,可以考虑:
- 数据分析:添加图表展示送水趋势
- 通知功能:空桶不足时自动提醒
- 多用户支持:不同配送员独立记录
- API 接口:提供标准的 REST API
- 数据备份:定期备份到其他存储服务
总结
Cloudflare Workers + KV 存储,虽然不是最新最热的技术,但对于这个场景来说,是最合适的选择。它提供了:
- 足够的性能
- 极低的成本
- 简单的开发体验
- 可靠的运行环境
项目代码已开源,感兴趣的朋友可以参考
