跳到主要内容

工程提炼:从 Folo 搬走什么

一、先把产品模型画清楚

Folo 最值得借鉴的不是某个库,而是它把 Feed、Subscription、List、Inbox、Entry、Summary、Translation 和 Chat 分成不同语义。领域模型一旦混乱,跨端复用只会把混乱放大。

二、依赖漏斗优于“共享一切”

共享包不是越多越好。共享层应该向下依赖稳定协议,平台壳层向上组合它们。最值得保留的边界是:

外部协议 -> Morph -> 领域 Model -> Store/DB -> UI selector -> 页面

每一层都能单独测试,也能在协议变化时收敛影响范围。

三、本地优先的四条纪律

  1. 本地 DB 是可恢复投影,不是随手的缓存;
  2. Store 是当前会话的即时投影,不替代持久化;
  3. 远端 API 是跨设备事实来源,但 UI 不必等待每次确认;
  4. 派生结果(摘要、翻译、Readability)永远可回退、可重建。

四、平台薄壳的真正难点

“业务共享、平台适配”听起来简单,真正难的是识别跨平台边界:

  • DB driver 不同,但 schema 相同;
  • Router 语义相同,但 history strategy 不同;
  • Auth 语义相同,但 Cookie/secure storage 不同;
  • UI 信息相同,但 DOM/RN 手势与虚拟列表不同;
  • 发布目标相同,但 Forge/EAS/OTA/Pages 不同。

应当把这些差异明确命名、集中实现,而不是让条件分支渗入所有业务文件。

五、流式与后台能力需要 durable state

AI Chat、播放器、同步、OTA 下载、推送和后台任务都有“页面卸载后仍在继续”的可能。它们必须有 controller、状态枚举、错误结果、重试/取消语义和持久记录。只靠 React effect 和临时变量,无法覆盖移动端挂起、桌面重启和网络抖动。

六、发布系统要像业务系统一样可观测

版本、渠道、runtime、制品和策略之间是关系图。发布脚本应提供明确输入、不可变引用、幂等上传和可回滚指针。Folo 把平台 tag、OTA manifest、R2/GitHub 资产和同步端点串起来,正是把“交付”变成系统模型。

七、如果重写 Folo,最先改哪里

以下是基于源码阅读的改进方向,不代表上游项目问题:

  • 为 Store action 统一记录 mutation 来源和版本,减少陈旧请求覆盖的隐式规则;
  • 把 client-sdk → local Model 的 Morph 映射按领域文件拆得更细,便于协议升级审查;
  • 为 DB 重建策略显式区分“可丢失缓存”和“不可丢失本地变更”;
  • 为 SSR server/client 包边界增加更严格的 lint 或构建检查;
  • 为 release graph 生成一份机器可读的兼容性矩阵;
  • 为 AI/后台任务统一抽象 cancellation、retry、trace 和 durable status。

八、最后的阅读框架

看一个大型跨端项目时,可以重复使用这六个问题:

  1. 数据的事实来源在哪里?
  2. 哪一层把外部协议翻译成本地语义?
  3. 哪些状态需要跨重启保存?
  4. 哪些能力需要跨页面继续运行?
  5. 平台差异被集中在哪些文件?
  6. 发布产物如何证明、分发和回滚?

只要这六个问题有清晰答案,目录再大也能被拆成可验证的链路。