为什么我重新做了 Kita,而不是继续修旧项目
这是“Kita 技术选择”系列的第四篇。前三篇确定了代码、开发环境和生产运行的基座;现在才轮到真正的问题:旧项目应该怎样进入这套新基座。
Kita 之前有一个叫 Kralgame 的项目。
它已经做过全屏首页、Games、Reviews、Wallpapers、Verses、About、Media 和 Users,也尝试过 Next.js 前端与 Payload 后端。最容易想到的迁移方式,是保留旧代码,再逐个修复依赖、接口和部署问题。
我最后没有这样做。
这不是因为旧项目毫无价值,恰恰相反:Kralgame 已经替我确认了最重要的东西——我究竟想做一个什么样的网站。
旧项目真正留下的是“意图”
Kralgame 让我确认,自己想做的不是普通企业后台,也不是只有文章列表的博客。
我想要的是带有 Galgame 和视觉小说氛围的个人内容站:
- 首页使用全屏图片、暗色遮罩、句子与雨滴玻璃效果;
- Games 像私人馆藏,而不是商店商品列表;
- Reviews 保存主观评价和长文;
- 文件资源只有在用户明确寻找时才出现;
- 页面应该安静,有自己的视觉性格。
这些选择比某个组件的实现更重要。
旧项目还帮助我试出了几个内容概念:Games 回答“这是什么,我整理了哪些资料”;Reviews 回答“我怎样看它”;资源目录回答“公开文件在哪里”。
所以重做 Kita 时,我没有从空白产品需求开始。我要恢复的是已经逐渐清楚的项目意图。
为什么旧代码无法成为可靠的起点
Kralgame 同时留下了另一类问题:
- mock 数据和真实请求混用;
- 前端存在硬编码 localhost 与不稳定 URL;
- Cloudinary、静态图片和上传方案没有统一;
- 组件知道过多后端查询细节;
- 依赖、配置和学习注释彼此纠缠;
- 原始数据库、环境和部署事实难以重建。
单独看,每个问题似乎都能修。把它们放在一起,修复顺序却很难确定。
例如一个 Games 页面显示失败,可能是组件问题、mock 字段问题、Payload schema 问题、API URL 问题,也可能只是旧数据库已经不存在。为了修一个可见症状,我需要先猜测多层已经失去事实来源的状态。
继续打补丁并不一定比重建更保守。它可能只是把旧的不确定性继续带进新项目。
“恢复旧项目”有两种完全不同的含义
我后来把恢复拆成两种:
1 | 恢复旧代码 |
对于一个拥有稳定测试、迁移和运行文档的成熟系统,继续演进通常比重写更安全。
但 Kralgame 当时缺少的正是这些安全网。它更像多个学习阶段的叠加快照,而不是可以逐步迁移的稳定产品。
因此 Kita 的原则变成:
继承 Kralgame 的气质和经验,不继承它的混乱。
我没有一开始就重建全部功能
“重新做”很容易滑向另一个陷阱:既然从头开始,就顺便设计一套更大、更完整的系统。
我最初也把“全栈项目”理解成必须拥有论坛、用户注册、评论、关注、收藏和复杂权限。后来我主动收缩了第一版范围:
- 不做公开用户注册;
- 不做评论和社交关系;
- 不做支付、订阅和商业后台;
- 不为架构感拆分微服务;
- 不预先加入 Redis、队列、邮件和复杂角色;
- 不使用决定页面气质的大型通用 UI 库。
范围收缩并不是放弃学习全栈。Kita 仍然需要页面、内容后台、数据库、媒体、容器、部署、备份和恢复。
我只是把完整性的定义从“功能很多”改成“已经选择的每条链路都能够闭环”。
为什么先恢复静态视觉
Kita 的重建顺序不是先设计所有数据库表。
我先让首页、Games 和主要导航在静态数据下成立。这样能够快速确认:页面是不是我想要的氛围,内容层次是否合理,封面画廊是否值得继续投入。
这时 mock 很有价值。它让 UI 不依赖数据库,可以专注验证布局和交互。
但我给 mock 设了明确边界:它只能验证页面,不能成为长期生产数据源。视觉确认以后,数据必须逐步进入 Payload 与 PostgreSQL。
这种顺序避免了两个极端:
- 先写大量后台,最后发现页面和内容方向并不喜欢;
- 永远停在漂亮 mock,无法录入、迁移和恢复真实内容。
哪些视觉实现被保留,哪些被重新选择
首页继续保留全屏背景、低干扰导航、随机句子和雨滴效果。
雨滴效果参考了 Codrops RainEffect 的底层思路,但 Kita 没有复制整个 demo,也没有引入 Three.js 和 GSAP。当前效果由 Canvas 2D 生成纹理,再由较小的 WebGL shader 完成折射与水层合成。
这里仍然遵循同一个取舍方法:保留能形成辨识度的核心效果,舍弃不解决当前问题的通用引擎和页面结构。
Games 则借鉴图片画廊的 columns 布局和 lightbox 交互,但使用自己的路由、数据模型和组件。参考项目帮助我解决一种交互,不代表它的存储和产品定位也必须一起进入 Kita。
重做不等于一次性设计正确
Kita 重建以后仍然经历了多次修改。
Games 图片从 coverKey 枚举走到静态路径,再走到 Payload Media 与 R2;开发环境从“不增加额外 volume”变成只为 .next 和 node_modules 增加 targeted volume;OpenList 从一个候选方向变成独立上线的应用。
如果重做的目标是一次性得到完美架构,那么这些变化看起来像失败。
我的目标并不是这样。新的基座只需要做到一件事:当判断发生变化时,我知道应该修改哪一层,也能说明旧方案为什么被替换。
Kita 当前保留的产品边界
经过收缩后,各页面和系统的职责变得更清楚:
| 页面或系统 | 当前职责 |
|---|---|
| Home | 建立全屏视觉与站点氛围 |
| About | 轻量介绍作者与项目 |
| Tools | 整理真正使用过的工具和资源 |
| Reviews | 保存主观评论、评分与长文 |
| Games | 保存游戏馆藏、元数据、状态和外部入口 |
| Payload Admin | 私有内容录入与管理 |
| OpenList | 独立公开资源目录 |
这个边界没有试图覆盖旧项目曾经出现过的所有页面,却更接近我真正会长期维护的内容。
下一步:静态页面必须接上真实数据
重新建立页面以后,Kita 已经恢复了 Kralgame 的视觉和内容意图。
接下来的问题不再是“页面长什么样”,而是:内容应该存在哪里,怎样从管理后台进入 PostgreSQL,又怎样安全地到达 Next.js 页面。
下一篇会写 Kita 从 mock 和静态页面走向 Payload Local API 的过程。













