轮子换了,车还没到

博客分类: 

SolidStart 2 上周正式 GA 了。创建者 Ryan Carniato 说得很直接:用 Vite 8 替换 Vinxi,直接使用 Vite 的 Environment API。25 个预发布版本,一年多的开发周期。

从外面看,这是一个框架在变好。从里面看,这是一个框架在承认之前的路走不通了。

Vinxi 走了,Vite 来了

Vinxi 是 SolidStart 1.x 的构建层,一个专门为 Nitro 服务端适配的构建编排工具。当初选它是因为 Vite 对 SSR 的支持还不够成熟,需要一个中间层来桥接。一年多过去,Vite 的 Environment API 逐渐完善,Vinxi 的价值就不大了。

这不是第一次。SvelteKit 从 Snowpack 切到 Vite,Next.js 从 Webpack 切到 Turbopack,Remix 也在反复调整构建层。元框架们像是在玩一个"换引擎"的游戏——车还在跑,但底盘每隔两年就得换一次。

做框架的人当然有理由:性能更好、架构更干净、社区更统一。但对于用框架做业务的前端团队来说,每次"换引擎"都意味着一轮迁移、一轮测试、一轮踩坑。

换引擎的代价谁在付

我们团队前年把一个内部工具从 Webpack 迁到 Vite,冷启动从 47 秒降到 3 秒,大家开心了一整天。但 Vite 处理 CommonJS 模块的方式跟 Webpack 不一样,我们花了两周排查一个第三方库加载失败的问题——Vite 预构建时跳过了那个库的 ESM 入口,而 Webpack 恰好能处理这种 case。debug 过程极其痛苦:报错信息指向的是预构建后的产物,你根本看不出原始模块的依赖链哪里断了。最后是手动给那个库加了一条 optimizeDeps.include 才解决。

然后呢?然后 Vite 6 出了,构建策略又有调整,之前在 Vite 4 上跑得好好的配置又要适配。

类似的事在另一个项目上也发生过。2024 年初给一个业务系统选构建工具,团队一致选了 Vite——成熟、快、社区大。半年后我们决定上微前端,引入 qiankun 之后才发现 Vite 和 qiankun 的兼容性问题比想象中多得多。子应用共享依赖时反复遇到"模块找不到"的错,明明在 package.json 里配了 externals,运行时却总是加载多份。我们花了两周才定位到问题根源:Vite 的预构建把一些依赖打包成了 chunk,而 qiankun 的沙箱机制对 chunk 加载做了拦截,两者打架了。那两周的加班时间,原本可以做两个完整的业务需求。

元框架的"元"是"连带"的意思

元框架跟纯框架不一样。框架是一个技术选择,元框架是一个技术组合——框架加构建工具加路由加部署约定。每换一次底层,影响都是系统性的。

SolidStart 2 不只是换了构建工具。SSR 管线从 Nitro 适配层重写为 Vite Environment 直连,之前基于 Vinxi 写的自定义插件全部作废。API 路由的数据序列化方式也不一样了,之前的 middleware 需要重写。对早期用户来说,这不是升级,是重新学一遍框架。

我见过一个更极端的例子。有个团队用了某个元框架的 1.x 版本做了大半年项目,框架出了 2.0,底层全换。框架维护者在 changelog 里写了一句"breaking changes are minimal"。那个团队的实际体验是:路由方案变了,数据加载方式变了,连部署产物结构都不一样。"minimal"是对框架维护者说的,不是对使用者说的。

框架稳定期在缩短

这让我想起一个技术管理中的经典问题:什么时候该跟进新版本,什么时候该坚守当前方案。

以前做技术选型,选一个框架可以用三五年。现在一个元框架的"稳定期"可能只有一两年。不是框架不想稳定,是它依赖的底层工具还在快速迭代,框架被迫跟着重构。

我们做技术选型时经常做一个假设:现在忍一下迁移成本,未来会省事。但当框架本身不稳定时,这个假设就不成立了。你刚忍完迁移成本,框架又给你制造了一轮新的迁移成本。

这个问题没有标准答案,但我见过两种应对方式。一种是紧跟最新版,每个大版本都跟,表面上技术债务少,实际上团队在持续付出学习成本。另一种是锁定版本,不轻易升级,错过新特性但保证稳定性。

两种策略的区别在于你怎么定义"技术债务"——框架版本落后算债务,还是被迫做大规模迁移算债务?前者是持续的零钱,后者是一次性的大额支出。我越来越觉得,对于 toC 产品,锁定版本可能是更划算的选择。稳定性带来的收益,往往比新特性的价值大。但我也不确定这个判断能撑多久——如果框架维护者决定不再维护旧版本,你还是得被动升级。

说到底,选框架不只是选技术,也是在选你跟不跟得上它的节奏。而这个节奏,现在越来越快了。

You voted 4. Total votes: 15

添加新评论