第一个 SaaS 框架 Saavo,折腾完了,还是不太满意

第一个 SaaS 框架总算准备发布了,记录一下这次折腾,以及现在回头看不太满意的地方。下一版有些想法,不过先用这个模板做几个项目再说。

W_Z_C1 min read

最近总算把第一个 SaaS 框架整理到了可以发布的程度,选了个短的名字 Saavo,没想到等框架发布了,我发现他奶奶的竟然有人也搞了一个网站也叫这个名称,当初购买域名的时候这个网站可没有。说实话,做完还是有点高兴的,毕竟以后再创建项目,总算有一个可以直接拿来用的模板了。不过回头看代码,整体上还是不太满意,已经开始想下一版应该怎么改了,貌似东西刚做完就想重写这个毛病,还是没有改掉……

1. 又造了一个轮子

做 SaaS 总有一些绕不过去的东西,登录、用户、支付、邮件、文件存储、多语言等等,具体产品还没开始写,先得把这些东西准备好。每次都重新搞一遍确实麻烦,所以这次把它们放进了一个模板,后面有新的想法,就可以直接在这个基础上继续做。

现在除了模板本身,还有创建项目的 CLI 和配套文档,可以从命令行下载模板、初始化本地环境,再按照文档配置需要的服务,最后部署上线。功能方面这里就不一个一个介绍了,具体可以看文档,这篇主要是想记录一下做完之后的想法,免得过一阵又忘了当初自己为什么这么选。

发布前又整理了一轮,发现需要处理的细节还真不少。例如内容集合是生成出来的,源码包里不应该带上,但删掉之后又得保证初始化时能重新生成,否则类型检查直接报错。再有图片,原来放在那里感觉没什么,打包之后才发现体积不小,又去清理没有使用的图片、压缩剩下的资源,图片格式换了之后,还得把网页和文档中的引用一起改掉。

文档也是,模板里的命令改了,文章里的说明就得跟着改,还得确认到底有没有漏掉。代码、模板、文档,单独看每一件事都不复杂,放到一起就容易出现这边改完,那边还是旧的情况。反正发布前又从头检查了一遍,总算把这些问题收拾了一下。

2. 做完之后的一些想法

首先还是结构的问题。目前框架整体上有些混乱,虽然层次划分比较明显,但有些地方做得并不好,特别是事务方面的处理,用起来不是很顺手。现在我还没有完全想清楚,究竟是这些地方没有设计好,还是这种分层方式本身就不太适合。单纯把每一层划清楚,好像也不能解决所有问题,代码放在哪里是一回事,真正写业务的时候顺不顺手又是另一回事。

我隐隐觉得,模块化可能会更合适,特别是对于 AI 编程的框架,想要什么功能就引入什么模块。比如需要支付,就把支付模块加进来,不需要的功能就不用带着,后面修改某个功能的时候,也尽量能在对应的模块里解决。听着倒是挺舒服,不过真要做起来,估计又是另一回事。

SaaS 里面这些功能并不是完全独立的,支付要知道用户是谁,用户又可能有订阅和权限,一个模块依赖另一个模块的时候怎么组织?底层能力谁来提供?配置和数据库的变更怎么处理?这些机制如果没有提前做好,最后很有可能只是把现在的代码换几个目录放进去,名字叫模块,改起来还是得牵着一大串,那就没什么意思了。所以这个方向我觉得可以研究,但对于框架底层的要求应该会比现在高不少。

再有就是登录认证,当初真不应该自己手写,麻烦不说,还浪费精力,现在回头看,应该直接使用 Better Auth 替代。造轮子的时候觉得自己处理也可以,做完再想想,这部分精力到底有没有必要花,还是有点后悔。新版准备把这部分换掉,没必要什么东西都自己维护。

渲染引擎同样如此,现在这部分是自己写的,我也不是很满意,当初应该选 TanStarter。奈何开始写这个 SaaS 模板的时候,按我当时了解的情况,TanStarter 还没有发布正式版,最后就自己搞了。现在再来看这个选择,总觉得有些地方绕了远路,不过已经写完了,总不能因为现在觉得另一个方案更好,就立刻把整个项目推翻重来。

目前对于下一版,我隐隐有一个想法,可能会使用 Void + TanStarter,再加上现在这个 SaaS 模板已经实现的功能,尽可能把各个模块拆清楚,最后组合到一起。具体怎么组合,哪些能力应该放到底层,哪些可以独立出去,目前还没有想清楚,先记在这里,省得过一阵又冒出别的想法,把这个给忘了。

不过这次准备先忍住,不急着研究下一版。以前折腾博客的时候,从 Ghost 换到 WordPress,再换到 Next.js,每次换的理由好像都挺充分,最后程序换了几轮,文章却没多写多少。这次如果也是模板刚做完,就开始研究另一个框架,估计过一阵又能写一篇重构记录,至于用它做的项目,可能还是没有几个……

所以接下来会一直用这个模板创建新的项目,多用一下里面的功能,有问题就改,把各个模块慢慢打磨出来。哪些功能确实重要,哪些需求值得做,哪些地方看着分层很清楚,用起来却到处别扭,总得真正做几个项目才能知道。等以后迁移、创建新框架的时候,也能知道自己到底要改什么,不然光凭现在这点感觉,换一种结构,没准还是一样的问题。

先用起来吧,下一版的事情等用过之后再说。