SvelteKit 3 进 RC:svelte.config.js 这个文件直接没了,$lib 改名 #lib——13 个破坏性变更锁定,升级窗口就是现在

SvelteKit 3 进 RC 了:svelte.config.js 这个文件直接没了,$lib 也改了名,Node 22 / TS 6 / Vite 8 三座门槛一起抬高——13 个破坏性变更已经锁定,升级窗口就是现在。

先给结论:这不是一次常规小版本,SvelteKit 3 是一次真正的大版本,而且是近几年前端框架里少见的”连迁移工具都一起给你了”的大版本。 Svelte 团队 8 月 13 日把 Kit 3 推到了 Release Candidate,意味着破坏性变更已经冻结,接下来只接受 bug 修复,stable 就在”数周之后”,不会再有新惊喜。对还在跑 SvelteKit 2 的项目来说,现在是从容迁移的窗口,而不是等着 stable 发布时被动救火。

三个会影响几乎所有项目的改动

第一,svelte.config.js 被删掉了。

以后所有配置都写进 vite.config.ts 里的 sveltekit() 插件调用。官方的理由是:异步解析配置太绕了,而且配置本来就该在一个地方,不是两个。

// 旧:svelte.config.js
import adapter from '@sveltejs/adapter-auto';
export default { kit: { adapter: adapter() } };

// 新:vite.config.js
import { sveltekit } from '@sveltejs/vite-plugin-svelte';
export default {
  plugins: [sveltekit({ adapter: adapter() })]
};

迁移是机械的:把导出的对象搬进插件参数,删掉旧文件,收工。

第二,$lib 换成了 #lib。

SvelteKit 2 里 $lib 别名指向 src/lib,这比 ../../../../somewhere 好看多了。但 SvelteKit 3 直接把它换成了 Node 原生的 subpath imports——也就是 package.json 里声明、Vite 和 TypeScript 都能原生解析的 #lib。好处是 SvelteKit 自己不用再维护一套协调代码了。

代价是一个小坑:Node 和 TypeScript 要求 subpath 导入必须无歧义,所以 #lib/foo 这种写法不行,得写成 #lib/foo.ts 或 #lib/foo/index.ts——必须带扩展名。

"imports": {
  "#lib": "./src/lib/index.js",
  "#lib/": "./src/lib/"
}

*第三,`$env/` 系列整体变成”显式环境变量”。**

$env/static/public、$env/dynamic/private、$app/environment 全都被标注为弃用,换成了在 src/env.ts 里统一声明的新体系。你要显式说明每个变量是 public 还是 private、是 build time 解析还是运行时解析,甚至可以用 Standard Schema 做校验。

// src/env.ts
import { defineEnvVars } from '@sveltejs/kit/env';
export const variables = defineEnvVars({
  PUBLIC_API_URL: { public: true, buildTime: true },
  DB_PASSWORD:   { public: false, buildTime: false }
});

换来的是:类型安全、可校验、build-time 变量能做 dead code elimination(直接摇掉),而且 import 时会自动补全。

顺手被清理掉的那些历史包袱

除了上面三个主线改动,这次还砍掉了一批让人翻旧文档才能理解的东西:

  • $app/stores 没了,page / navigating / updated 全搬到 $app/state,基于 Svelte 5 runes 重写——用的时候记得把 $ 前缀去掉。
  • $service-worker 模块没了,替代品是 $app/manifest 和 $app/service-worker,service worker 终于有正经类型了。
  • tsconfig.json 不用再 extend 那个丑丑的 ./.svelte-kit/tsconfig.json,改成 extend $app/tsconfig,而且里面塞了更多推荐配置,多数项目可以把自定义的 compilerOptions 删掉。
  • 错误处理大改:SvelteKit 2 受制于要兼容 Svelte 4(没有 error boundary 概念),只能在 load 出错时显示 +error.svelte。Kit 3 强制 Svelte 5,渲染期错误也能接住;而且你主动 error(...) 抛出的错误现在也会过一遍 handleError——以前会被忽略,因为它假定你已经自己处理了。另外,堆栈开始应用 sourcemap 了。
  • 浅路由换 API:从 pushState / replaceState 换成 goto(..., { shallow: true }),而且浅导航现在会正常触发 beforeNavigate,还能用 persistState: true 跨刷新保留页面状态。

门槛抬高了,Vite 8 是真正会卡住你的那一个

SvelteKit 3 不是”支持”了 Vite 8,而是要求 Vite 8。其他最低版本要求:

  • Node.js v22.17+
  • TypeScript v6+
  • Svelte v5.56.4+
  • Vite v8.0.12+
  • @sveltejs/vite-plugin-svelte v7+

Vite 8 自带 Rolldown 作为打包器——一个用 Rust 重写的、替代 esbuild + Rollup 的实现。构建确实快得多,但它破坏了和老插件的兼容性。所以迁移流程里最容易翻车的一步不是改代码,是:先审你的 Vite 插件清单,再动迁移。

现在该做什么

官方给了迁移工具,这一版 SvelteKit 罕见地把大版本升级的机械工作自动化了:

# 迁移已有项目
npx sv@next migrate sveltekit-3 --tasks all --confirm

# 新建项目
npx sv@next create my-new-app

它会把配置搬家、把 $lib 批量改成 #lib、迁移 $env 引用。搞不定的部分,它会生成一份带 @migration 标注的 TODO 清单,交给你的”clanker”(它原话)去逐条处理。跑不兼容的代码时,Kit 会打印诊断警告和错误,不会让你盲猜。

推荐顺序是:

  1. 先升到最新的 SvelteKit 2.x——它会打印一堆针对性的弃用警告,让你的 TODO 清单变短;
  2. 再跑迁移工具;
  3. 审一遍 Vite 8 插件兼容性;
  4. 最后拿 RC 冒烟测试(npm i @sveltejs/kit@next)。

至于 Remote Functions——它是这一版真正的方向(query / command / form / prerender 四类,把客户端和服务端通信做成了类 tRPC 的 RPC 调用),但目前仍然带 experimental 标记,API 还可能变,别急着上生产。不过它在 RC 阶段已经够稳定,值得提前熟悉,因为 load function 那套模式确实在往后退。

一句话收尾:SvelteKit 3 的意义不是”又一个 breaking change”,而是它第一次连”怎么从 2 迁到 3″都替你想好了。 有迁移工具、有诊断警告、有 deprecated 预告,这种升级体验在前端框架里是稀缺品。窗口就摆在现在,等 stable 再动手,你只是在给自己制造截止日期。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 1530 阅读