成为全栈·产品篇·技术选型不是投票
成为全栈·产品篇·技术选型不是投票本文目标拆清楚这套专栏每个端的技术栈是怎么定的尤其要把后端栈Hono Drizzle Cloudflare D1/R2为什么「已经定死」讲透。更重要的是把背后的选型方法论交给你——这套方法能迁移到你自己的任何项目比记住某个框架名字值钱。前置知识建议先读 用一个真实系统串起全栈七个子项目全貌。本文会展开那张七端表格里每个端的技术栈。先澄清一个常见误会很多人以为「技术选型」是投票团队里谁嗓门大、哪个框架 GitHub 星多就选哪个。或者更随意——「大家都在用我也用」。这是本末倒置。选型是按约束定的不是按人气定的。而且我们有条铁律每次选型都必须写理由——交代备选方案和取舍依据。这恰恰是本系列区别于普通教程的核心普通教程告诉你「用这个」我们只告诉你「为什么是它以及什么时候该换」。还有一点要先说在前本文标题写「七个子项目技术栈的定法」但后端栈其实在 M1 动手前就已经定死了本文是「反向约束」——它先存在然后要求我把理由讲清楚。所以你读到的不是「我们现场选」而是「它已经定了我来拆解这个决策」。这个区别很重要。一、选型的方法论按约束定不是集美投票做选型时我会把约束摊在桌面上看它们互相怎么打架约束它要什么团队熟悉度别选没人会、踩坑没人填的部署环境跑在 Cloudflare 还是自管 Linux这决定数据库和存储选型成本serverless 按量计费 vs 常驻服务器月租量级差很多生态与长期维护框架是不是还在活跃迭代、文档全不全与现有栈的契合前端已是 TypeScript 体系后端能不能共用一套类型关键不在列出约束而在约束会互相打架。比如「想用 Cloudflare 省运维」和「又想能随时搬回普通 Linux 服务器」就是一对矛盾——这正是后面适配层要解决的。选型不是找「全 5 分」的选项而是在矛盾里做权衡、并能说清「我为什么这么让」。把这条决策链画成图谁是根、谁是被约束的结果一眼就清楚二、后端栈为什么已经定死Node 后端M1采用Hono Drizzle ORM Cloudflare D1数据库 Cloudflare R2对象存储并且同时兼容部署在普通 Linux 服务器。它定死是因为它是七端的共同地基——所有前端、App、小程序都消费它产出的同一套 API。地基不能每个端换一套否则「一个系统七端共享契约」的复利就垮了。逐个说理由Hono超轻量、跨运行时的 Web 框架。同一份代码能跑在 Cloudflare Workers、Node、Bun、Deno。这一点对「一套后端两种部署目标」是前提——框架本身就不过度绑定某个运行时。Drizzle ORMTypeScript 原生、类型安全更关键的是在 Cloudflare 用 D1SQLite在 Linux 上用 SQLite 文件或 PostgreSQLschema 不变。你写的表结构换数据库不用重写。D1 / R2Cloudflare 生态的数据库与对象存储。它们最大的卖点是零运维、按量计费——对个人项目和副业极其友好。对应到 Linux 上就是 SQLite/PostgreSQL 与本地磁盘 / S3 / MinIO。你看这一套选型的底层逻辑就一句话用 serverless 把运维和成本压到最低同时用 Hono Drizzle 的跨运行时特性保住「随时能搬回普通 Linux」的退路。三、唯一的陷阱也是高价值解法适配层上面那句「保住退路」不是白说的。D1/R2 是 Cloudflare 专有服务但真实世界里你完全可能要在自己的 Linux 服务器上跑同一套系统。这就有个矛盾业务逻辑只有一份但底层存储D1 vs SQLite/Postgres、R2 vs 本地磁盘/S3是两套。解法就是本系列一个高价值题材写一层「适配层」让同一份业务逻辑在边缘Cloudflare和自管服务器Linux上都能跑。业务逻辑不直接调用 Cloudflare 专有 API而是调用适配层暴露的统一接口适配层在两种部署目标下各自实现。把「一份逻辑、两种落地」画成图就是典型的「中间件隔离」结构这带来一个很妙的副产品——「一套后端两种部署目标」本身就是值得单独成篇的内容{{LINK:M1-24}} 会专门讲适配层抽象。你学到的不只是「怎么接 Cloudflare」而是「怎么写出不绑定任何云厂商的业务代码」这套能力到哪都用得上。连附件存储也是同一思路上传走适配层R2 为主、本地磁盘兜底由一个STORAGE_DRIVER配置驱动。你看架构约束一旦想清楚连文件存储都自动跟着整齐了。四、前端各端按场景选不统一后端栈定死但前端各端是自由选型的——因为它们是「端」不是「地基」。每个端按自己的场景挑最合适的框架端技术栈为什么是它M2 管理后台Vite React后台要的是开发效率和组件生态React 成熟稳妥M3 网站前台Next.jsApp Router要 SEO且能在框架内直接写后端Route Handler / Server Actions读者前台首选M4 AppFlutter一套代码出双端原生 App跨平台体验一致M5 小程序Taro用 React 语法写微信小程序前端心智零切换M7 后台重写Vue3同契约重写展示换一套前端框架是什么体验注意这里的自由边界框架可以换契约不能换。你用 React 还是 Vue 写后台是选型自由但无论哪个框架调用的都是同一套 API。这正是 用一个真实系统串起全栈 说的复利——地基不变端随便长。五、Go 后端重写语言是变量契约是常量最后说 M6。它用Go 把同一套后端重写一遍接口与 Node 版完全一致。这件事的启示很锋利当你做技术选型时编程语言只是变量系统设计契约才是常量。你今天用 Node、明天用 Go换的是工具实体关系、鉴权模型、错误码约定这些「设计」是一次想清楚、长期不变的东西。所以如果你纠结「我该学 Node 还是 Go」换个问法更有价值「我的系统设计清楚了吗」设计清楚了换语言只是体力活。给你一句可带走的心法下次面对选型先别问「哪个好」先拿一张纸把约束列出来——团队会不会、跑在哪、多少钱、生态活不活、和现有栈契不契合。列完你会发现很多「纠结」其实是因为你还没把约束摊开。方法比结论耐用今天这个结论可能过时但「按约束定、写理由」这套动作到你下一个项目仍然成立。顺便这套「契约是常量」的认知会反过来治你的选型焦虑当你不再纠结「该学哪个框架」而是先问「我的系统设计清楚了吗」你就已经站在全栈的门槛上了。把这句记下来它会在你后面每一次选框架时跳出来提醒你。小结选型按约束定不是投票每次选型必须写理由——这是本系列区别于普通教程的核心。后端栈Hono Drizzle D1/R2已经定死因为它是七端共同地基理由就一条serverless 压成本跨运行时保退路。唯一的陷阱是 Cloudflare 锁定解法是一层适配层——「一套后端两种部署目标」本身是高价值内容。前端各端自由选型按场景但契约不变M6 用 Go 重写证明语言是变量、设计是常量。真正要带走的不是某个框架名而是「把约束摊开、做权衡、写理由」这套方法论。延伸阅读用一个真实系统串起全栈——本文展开的就是那张七端表格里的技术栈。——本文展开的就是那张七端表格里的技术栈。{{LINK:M0-04}}《领域建模》——下一篇讲「设计是常量」里那个不变量实体和关系怎么定。订阅这个专栏如果你也想跟着一个真实系统从「调接口的人」走到「设计系统的人」欢迎订阅我的《成为全栈开发工程师》专栏。后续每篇都会带着可运行的代码和完整的设计取舍走下来欢迎在评论区讨论、指正。本系列专栏https://blog.csdn.net/fungleo/category_13204651.html订阅看全部篇章完整项目仓库https://github.com/fengcms/become-a-full-stack-developer