SvelteKit 3 已进入 Release Candidate 阶段。这个版本没有把重点放在堆叠新功能上,而是清理现有代码、统一配置边界,并为后续演进打基础。对项目维护者来说,最需要关注的变化有三个:配置进一步移入 vite.config.ts、内置别名由 $lib 改为 #lib,以及最低依赖提升到 Svelte 5 和 Vite 8。
RC 仍不等于稳定版。适合现在动手的是迁移分支、测试环境和内部项目,而不是在没有回滚方案的情况下直接升级关键生产系统。
配置向 Vite 集中意味着什么
过去的 SvelteKit 项目可能同时在 svelte.config.js、vite.config.ts 和其他工具配置中处理构建行为。SvelteKit 3 将更多配置归并到 Vite,能够减少同一构建选项分散在多个文件中的情况,也让插件组合和构建问题更容易沿着 Vite 的执行链排查。
一个最小的 vite.config.ts 可以这样写:
import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
export default defineConfig({
plugins: [sveltekit()]
});
升级时不要直接删除原有的 svelte.config.js。适配器、预处理器以及某些实验性选项是否仍保留在该文件中,应以当前 RC 版本的类型提示和迁移说明为准。更稳妥的方式是逐项移动配置,并在每一步运行类型检查和构建:
npm run check
npm run build
npm run preview
如果项目使用自定义 Vite 插件,还应检查插件顺序以及它们对虚拟模块、SSR 和路径解析的处理。配置文件合并之后,选项冲突通常更容易发现,但插件之间的执行顺序仍可能改变最终结果。
$lib 迁移到 #lib:小改名,大范围搜索
SvelteKit 3 用 #lib 替换 $lib,目的是改善与其他工具和模块解析机制的兼容性。代码本身的变化很直观:
// 迁移前
import { formatDate } from '$lib/date';
import Button from '$lib/components/Button.svelte';
// 迁移后
import { formatDate } from '#lib/date';
import Button from '#lib/components/Button.svelte';
真正容易遗漏的地方不只是 .svelte 和 .ts 文件,还包括测试、Storybook、脚本、代码生成模板以及 ESLint 或 TypeScript 配置中的路径映射。可以先用 ripgrep 做一次完整盘点:
rg -n '\$lib' . \
--glob '!node_modules/**' \
--glob '!build/**' \
--glob '!.svelte-kit/**'
下面这个 Node.js 脚本可以批量修改常见源码文件。运行前先提交当前改动,执行后仍需人工审查差异:
node --input-type=module <<'NODE'
import { readdir, readFile, writeFile } from 'node:fs/promises';
import { extname, join } from 'node:path';
const roots = ['src', 'tests'];
const extensions = new Set(['.svelte', '.ts', '.js', '.mjs', '.cjs']);
async function migrate(directory) {
let entries;
try {
entries = await readdir(directory, { withFileTypes: true });
} catch (error) {
if (error.code === 'ENOENT') return;
throw error;
}
for (const entry of entries) {
const file = join(directory, entry.name);
if (entry.isDirectory()) {
await migrate(file);
continue;
}
if (!extensions.has(extname(entry.name))) continue;
const source = await readFile(file, 'utf8');
const updated = source.replaceAll('$lib', '#lib');
if (updated !== source) {
await writeFile(file, updated);
console.log(`updated ${file}`);
}
}
}
for (const root of roots) {
await migrate(root);
}
NODE
npm run check
npm test
npm run build
这里使用的是纯文本替换,因此它也会修改注释和字符串。通常这正是迁移想要的结果,但仍应通过 git diff 检查是否误改了文档示例、快照或与 SvelteKit 无关的字面量:
git diff -- src tests
rg -n '\$lib' . --glob '!node_modules/**' --glob '!.svelte-kit/**'
依赖基线:Svelte 5 与 Vite 8
SvelteKit 3 要求 Svelte 5 和 Vite 8。这意味着升级不能只修改 @sveltejs/kit,还要一起检查编译器、Vite 插件、测试工具、适配器和部署平台。
可以先查询实际发布的 RC 版本,再显式安装,避免仅凭示例猜测版本号:
npm view @sveltejs/kit versions --json
npm view @sveltejs/kit dist-tags
确认版本后,可以这样安装;把环境变量替换成准备验证的真实 RC 版本:
export KIT_RC_VERSION='3.0.0-rc.X'
npm install --save-dev "@sveltejs/kit@$KIT_RC_VERSION" 'svelte@^5' 'vite@^8'
如果使用 pnpm 或 Yarn,也应保留现有包管理器和锁文件,不要在迁移过程中顺便切换工具。升级完成后检查是否出现多份 Svelte 或 Vite:
npm ls @sveltejs/kit svelte vite
这个版本的目标还包括改善错误处理和构建效率。不过在自己的项目里,应通过构建日志和基准数据验证效果,而不是假定所有工作负载都会自动变快。至少记录升级前后的冷启动、生产构建耗时、输出体积和 SSR 测试结果。
RC 阶段的落地顺序
SvelteKit 3 仍保留部分实验性能力,因此实验 API、第三方适配器和深度依赖 Vite 内部行为的插件,都是风险较高的区域。推荐按下面的顺序推进:
- 从主分支创建独立迁移分支,并保留当前锁文件。
- 升级到 Svelte 5、Vite 8 和明确的 SvelteKit 3 RC 版本。
- 将
$lib全量替换为#lib,同时检查测试与工具配置。 - 按 RC 的类型定义逐项整理
vite.config.ts和原有 Svelte 配置。 - 运行类型检查、单元测试、SSR 测试、生产构建与预览。
- 验证所用 adapter、Vite 插件和部署平台是否声明支持新版本。
- 等稳定版发布后,再根据最终迁移说明清理临时兼容代码。
这次升级的工作量主要不在业务组件,而在工程边界:配置归属、模块别名和工具链版本。提前在 RC 阶段清理这些依赖,可以降低正式版升级时一次性处理大量构建问题的风险;代价则是需要接受 RC 期间仍可能发生细节调整,并为回滚保留清晰路径。