mcpField
S
sveltekit-config

sveltekit-config

github.com/full-stack-skills开发469 次安装4 周前更新
代码仓库

关于 sveltekit-config

sveltekit-config 是面向 SvelteKit 配置、构建与部署任务的参考技能,也涵盖路由、性能、图像、无障碍、SEO、调试和迁移。适用于处理框架配置与生产环境问题的开发者。

主要功能

  1. 01适配器选择与部署配置
  2. 02高级路由和布局模式
  3. 03认证集成与性能优化
  4. 04图像处理与无障碍实践
  5. 05SEO、调试和版本迁移

适用场景

  1. 01为目标平台配置 SvelteKit 适配器
  2. 02设计高级路由与布局结构
  3. 03排查性能、图像或无障碍问题
  4. 04处理 SEO 配置或迁移到新版

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/full-stack-skills/svelte-skills --skill sveltekit-config

安装后在 Claude Code 中输入/sveltekit-config确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
examples/
accessibility.md
adapter-cloudflare.md
adapter-netlify.md
adapter-node.md
adapter-static.md
adapter-vercel.md
advanced-layouts.md
advanced-routing.md
build-preview.md
debugging.md
images.md
migration-v2.md
performance.md
README.md
seo.md
writing-adapter.md
references/
a11y-reference.md
adapters-comparison.md
auth-reference.md
building-reference.md
debugging-reference.md
images-reference.md
layouts-advanced-reference.md
migration-sapper-reference.md
migration-v1-v2-reference.md
performance-reference.md
README.md
routing-advanced-reference.md
seo-reference.md

详细介绍

SvelteKit 配置

何时使用此技能

在处理 SvelteKit 的配置、构建流程、部署、性能、图像、无障碍、SEO、调试或迁移相关问题时,都应使用此技能。这包括:

  • 选择或配置适配器(adapter-node、adapter-static、adapter-cloudflare、adapter-netlify、adapter-vercel)
  • 构建(vite build)和预览(vite preview)生产应用
  • 高级路由(rest 参数、可选参数、匹配器、路由排序、文件名编码)
  • 高级布局(路由组、使用 @ 跳出布局)
  • 身份验证集成模式(会话与令牌、基于 hooks 的身份验证)
  • 性能优化(代码拆分、资源优化、避免瀑布式加载)
  • 图像处理(@sveltejs/enhanced-img、CDN 加载、<picture>/<img> 模式)
  • 无障碍(路由公告、焦点管理、lang 属性)
  • SEO(标题、元标签、站点地图、JSON-LD)
  • 断点调试(VS Code、Chrome DevTools)
  • 从 SvelteKit v1 或 Sapper 迁移

有关路由、数据和 load 基础知识,请参阅 sveltekit-overview。有关 Svelte 组件和 runes,请参阅 svelte-runes。

关键:构建和预览

vite build 分两个阶段运行:Vite 生成优化后的生产构建,然后由适配器针对目标平台调整输出。预渲染会在构建期间执行。

构建期间,SvelteKit 会加载你的 +page/layout(.server).js 进行分析。必须避免在构建时运行的代码,应使用 $app/environment 中的 building 进行保护:

import { building } from '$app/environment';
import { initialiseDatabase } from '$lib/server/database';

if (!building) initialiseDatabase();

export function load() { /* ... */ }

构建完成后,运行 vite preview(或 npm run preview)在本地测试生产构建。预览在 Node 中运行,因此适配器特有的行为(例如 Cloudflare 的 platform 对象)不会生效——请使用 wrangler dev 测试 Cloudflare,或使用平台的 CLI 进行准确测试。

npm run build       # vite build + adapter
npm run preview     # vite preview (Node)

关键:适配器——如何选择

适配器在 svelte.config.js 的 kit.adapter 下配置。新项目默认附带 adapter-auto,它会为已知的部署环境(Cloudflare Pages、Netlify、Vercel、Azure SWA、SST、Google Cloud Run)选择合适的适配器。选定目标后,请显式安装对应的适配器,使其加入锁文件。

目标适配器说明
Node 服务端 / Docker / VM@sveltejs/adapter-node独立的 Node 服务端。灵活性最高。
静态托管(无 SSR)@sveltejs/adapter-staticSSG 或 SPA 回退。
Cloudflare Workers / Pages@sveltejs/adapter-cloudflare适用于两者的统一适配器。
Netlify@sveltejs/adapter-netlifyNode 函数或 Deno 边缘运行时。
Vercel@sveltejs/adapter-vercel无服务器或边缘运行时,支持 ISR。

适配器快速指南:

// svelte.config.js
import adapter from '@sveltejs/adapter-node';
export default { kit: { adapter: adapter() } };
平台特定上下文

某些适配器会通过 hooks/服务端路由中的 event.platform 提供平台信息(KV 命名空间、Durable Objects、环境变量)。在 src/app.d.ts 中进行类型扩展:

declare global {
  namespace App {
    interface Platform {
      env: { MY_KV: KVNamespace };
    }
  }
}
export {};

环境变量始终优先使用 $env/static/private——预渲染期间无法使用 $env/dynamic/*。

关键:高级路由

SvelteKit 路由基于文件系统。除基本动态片段外,还提供多种高级功能。

Rest 参数——[...rest]

匹配数量不定的片段。src/routes/a/[...rest]/z/+page.svelte 可匹配 /a/z、/a/b/z、/a/b/c/z。rest 参数是一个以 / 分隔片段的字符串。

src/routes/[org]/[repo]/tree/[branch]/[...file]/+page.svelte

使用 rest 参数呈现自定义 404 页面——添加 [...path]/+page.js 并调用 error(404),以便进入嵌套的 +error.svelte。

可选参数——[[lang]]

使用双括号包裹参数即可使其可选。[[lang]]/home 可匹配 /home 和 /en/home。rest 参数后不能跟可选参数。

匹配 — [name=type]

使用 src/params/ 中的匹配器约束参数:

// src/params/fruit.js
/** @type {import('@sveltejs/kit').ParamMatcher} */
export function match(param) {
  return param === 'apple' || param === 'orange';
}

然后编写 src/routes/fruits/[page=fruit]/+page.svelte。匹配器会在服务器和浏览器端运行。

排序

多个路由匹配时,SvelteKit 按以下顺序排序:

  1. 更具体的路由优先(参数越少越具体)
  2. 匹配器([name=type])优先于不受约束的参数([name])
  3. [[optional]] 和 [...rest] 的优先级最低,除非它们是最后一段
  4. 平局时按字母顺序排序
对特殊字符进行编码

在文件夹名称中使用十六进制转义 [x+nn]:/ → [x+2f]、: → [x+3a] 等。Unicode 字符使用 [u+nnnn](无需使用代理对)。

src/routes/smileys/[x+3a]-[x+29]/+page.svelte
# matches /smileys/:-)

重要:高级布局

默认情况下,布局层级与文件夹层级相对应。使用以下模式重新构造布局层级。

路由组 — (group)

用括号包裹的文件夹名称不会出现在 URL 中。可用于让多个路由共享布局,同时不影响 URL 结构。

src/routes/
├ (app)/dashboard/+page.svelte
├ (app)/+layout.svelte          # app shell
├ (marketing)/about/+page.svelte
├ (marketing)/+layout.svelte    # marketing shell
└ +layout.svelte
跳出布局 — [email protected]

追加 @<segment>(根布局使用 @),即可重置布局链。+page@(app).svelte 仅继承 (app)/+layout.svelte。

选项:+page@[id].svelte、[email protected]、+page@(app).svelte、[email protected]。

布局也可以跳出:[email protected] 会将其下所有内容的布局链重置到根布局。

重置到根布局

如果你想让应用的大部分内容使用同一个布局,但让少数路由跳出该布局,可以把除例外路由以外的所有内容都放在一个组中:

src/routes/
├ (app)/...
└ admin/+page.svelte   # does NOT inherit (app) layout

重要:身份验证集成

身份验证 = 认证(你是谁?)+ 授权(你能做什么?)。

会话与令牌
  • 会话:ID 存储在数据库中。可立即撤销,但每个请求都需要查询数据库。
  • JWT 令牌:包含所有必要信息,无需查询数据库,但无法立即撤销。延迟更低。
集成模式

在 src/hooks.server.js 中检查身份验证 Cookie,将 event.locals.user 填充为用户信息,然后在 +page.server.js / +server.js 的加载函数中读取 locals。

// src/hooks.server.js
export async function handle({ event, resolve }) {
  event.locals.user = await getUser(event.cookies.get('session'));
  return resolve(event);
}
库
  • npx sv add better-auth — 通过 Svelte CLI 集成 Better Auth
  • Lucia 身份验证指南 — 参考其中基于会话的 SvelteKit 示例

在 SvelteKit v2 中调用 cookies.set(...) 时,始终指定 path: '/'。

重要:性能优化

SvelteKit 内置了代码分割、资源预加载、文件哈希、请求合并、并行加载、数据内联、保守失效和链接预加载。若要进一步优化:

诊断
  • PageSpeed Insights / Lighthouse / WebPageTest
  • Chrome DevTools 的 Network 和 Performance 标签页
  • 在预览模式下测试(运行 vite build 后),而非开发模式
资源
  • 使用 @sveltejs/enhanced-img 处理图片(生成更小的格式、设置固有尺寸)
  • 使用 preload="none" 延迟加载首屏以下的视频
  • 精简字体子集;通过 handle 钩子的 preload 过滤器预加载关键字体
代码体积
  • 使用 Svelte 5(比 Svelte 4 更小)
  • 使用 rollup-plugin-visualizer 查找体积较大的软件包
  • 条件代码优先使用动态 import()
  • 将第三方脚本移至 Web Worker(Partytown)
避免瀑布式请求
  • 后端调用使用服务器端 load 函数(避免客户端 → 服务器 → 后端的请求链)
  • 使用 Promise.all / 数据库联接并行执行查询
  • SPA 模式会导致瀑布式请求 — 改用预渲染
托管
  • 将前端部署在靠近后端的位置(或使用边缘节点)
  • 确保支持 HTTP/2+

重要:图片

Vite 内置处理
<script>
  import logo from '$lib/assets/logo.png';
</script>
<img alt="logo" src={logo} />

Vite 会对文件名进行哈希处理,并内联较小的资源。

@sveltejs/enhanced-img

构建时优化图片:生成 avif / webp,设置固有的 width / height(避免 CLS),移除 EXIF 信息。

// vite.config.js — plugin order matters
import { enhancedImages } from '@sveltejs/enhanced-img';
import { sveltekit } from '@sveltejs/kit/vite';
export default { plugins: [enhancedImages(), sveltekit()] };

用法:

<enhanced:img src="./image.jpg" alt="..." sizes="min(1280px, 100vw)" />

生成的 <picture> 会包含多种格式和尺寸,以适配 HiDPI 显示屏。为 Retina 显示屏提供 2x 源图。

自定义宽度:<enhanced:img src="./image.png?w=1280;640;400" /> 单张图片的变换:<enhanced:img src="./image.jpg?blur=15" />

动态 CDN 加载

对于构建时无法获取的图像(CMS、数据库),请使用 CDN 库:

  • @unpic/svelte — 不依赖特定 CDN
  • svelte-cloudinary — Cloudinary
  • CMS 内置支持:Contentful、Storyblok、Contentstack
最佳实践
  • 对 LCP 图像设置 fetchpriority="high",避免使用 loading="lazy"
  • 始终提供 alt 文本
  • 在 sizes 中不要使用 em/rem
  • 混合使用不同策略:使用 Vite 处理 <meta>,使用 enhanced-img 处理主视觉图像,使用 CDN 处理用户内容

重要:无障碍访问

SvelteKit 提供了无障碍基础支持;你仍需负责应用级别的无障碍访问。

路由播报

SvelteKit 会注入一个实时区域,在每次客户端导航后播报 <title>。每个页面都必须在 <svelte:head> 中包含唯一且描述性明确的 <title>:

<svelte:head>
  <title>Todo List</title>
</svelte:head>
焦点管理

每次导航后,SvelteKit 会将焦点设在 <body> 上(如果存在 [autofocus] 元素,则设在该元素上)。使用 afterNavigate 覆盖此行为,实现自定义逻辑:

import { afterNavigate } from '$app/navigation';
afterNavigate(() => document.querySelector('.focus-me')?.focus());

在 <form> 上使用 data-sveltekit-keepfocus 可保留输入焦点。编程式导航可使用 goto(url, { keepFocus: true })。

lang 属性

在 src/app.html 中设置 <html lang="en">(或你的语言)。对于多语言网站,使用 handle 中的 transformPageChunk 按请求设置语言。

重要:SEO

SvelteKit 内置 SSR、规范化的尾斜杠 URL 和良好的默认设置。手动操作步骤:

每页元数据
<svelte:head>
  <title>Page Title — Site Name</title>
  <meta name="description" content="..." />
  <meta property="og:title" content="..." />
  <meta property="og:description" content="..." />
  <meta property="og:image" content="..." />
  <meta property="og:type" content="website" />
  <link rel="canonical" href="https://..." />
</svelte:head>

常见模式:从 load 返回 SEO 数据,并在根布局的 <svelte:head> 中渲染。

Sitemap
// src/routes/sitemap.xml/+server.js
export async function GET() {
  return new Response(`<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      
    </urlset>`, { headers: { 'Content-Type': 'application/xml' } });
}
JSON-LD 结构化数据

通过 <svelte:head> 注入,并使用 <script type="application/ld+json">。

重要:迁移

SvelteKit v1 → v2

使用 npx sv migrate sveltekit-2(对于较旧的项目,可使用 npx svelte-migrate)。破坏性变更:

  • error(...) 和 redirect(...) 不再抛出异常——只需调用它们
  • cookies.set/delete/serialize 需要 path: '/'
  • load 中顶层的 Promise 不会自动等待——请显式使用 await
  • goto 不再接受外部 URL(请使用 window.location.href)
  • paths 现在统一使用相对路径(默认值为 true)
  • $app/stores 在 2.12 中已弃用——迁移到 $app/state(Svelte 5 runes)
  • 需要 Svelte 4,Node 18.13+
  • 必须从 @sveltejs/vite-plugin-svelte 导入 vitePreprocess
Sapper → SvelteKit
  • package.json:添加 "type": "module",移除 polka/sapper/sirv/compression
  • 添加 @sveltejs/kit 和一个适配器
  • 脚本:sapper build → vite build,sapper dev → vite dev,node __sapper__/build → node build
  • src/template.html → src/app.html(替换 %sapper.* 占位符)
  • 路由:routes/about/index.svelte → routes/about/+page.svelte
  • _layout.svelte → +layout.svelte,_error.svelte → +error.svelte
  • preload → load(API 不同:只有一个 event 参数,没有 this.fetch)
  • $app/stores(或 2.12+ 中的 $app/state)中的 stores / navigating
  • 正则路由 → src/params/ 中的匹配器
  • sapper:prefetch → data-sveltekit-preload-data
  • sapper:noscroll → data-sveltekit-noscroll
  • 将内部库从 src/node_modules/... 移至 src/lib

重要:调试

VS Code

内置调试终端开箱即用:

  1. CMD/Ctrl+Shift+P → “Debug: JavaScript Debug Terminal”
  2. 在该终端中运行 npm run dev
  3. 设置断点,然后在浏览器中触发断点

或者创建 .vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    { "command": "npm run dev", "name": "dev", "request": "launch", "type": "node-terminal" }
  ]
}
Chrome DevTools / Edge
NODE_OPTIONS="--inspect" npm run dev

打开网站,然后点击“为 Node.js 打开专用 DevTools”图标(左上角的 Node 标志)。也可以访问 chrome://inspect。

快速修复

  • building 标志:将一次性初始化代码包在 if (!building) 中,避免它在 vite build 期间运行。
  • adapter-static 中的 fallback:SPA 模式使用 200.html,但避免使用 index.html(它会与预渲染的 / 冲突)。
  • GitHub Pages:将 paths.base 设置为仓库名称,并设置 fallback: '404.html'。在 static/ 中添加 .nojekyll。
  • Node origin:如果你位于代理之后并看到 "Cross-site POST form submissions are forbidden",请设置 ORIGIN 环境变量。
  • XFF 深度:如果位于 N 个代理之后,请设置 XFF_DEPTH=N,这样 getClientAddress() 就会返回真实的客户端 IP。
  • 压缩:使用 @polka/compression,而不是 compression——SvelteKit 会以流的形式发送响应。
  • 生产环境中的 .env:生产环境不会自动加载 .env。使用 node --env-file=.env build(Node 20.6+)或 -r dotenv/config。
  • platform 仅在 dev/preview 中可用:使用相应的平台 CLI(wrangler dev、netlify dev、vercel dev)测试 Cloudflare/Netlify/Vercel 平台 API。
  • fs 不可用:使用 $app/server 中的 read(在边缘环境中,它会从已部署的资源获取内容)。
  • goto 外部 URL:改用 window.location.href。
  • Cookie 路径:SvelteKit v2 要求在 cookies.set(...) 中设置 path: '/'。
  • 尾部斜杠:如果你的主机无法通过 /a 提供 /a.html,请设置 trailingSlash: 'always'。

注意事项

  • 预览环境不是生产环境:vite preview 在 Node 中运行,不会模拟适配器特有的行为。请使用平台的 CLI 进行准确的本地测试。
  • adapter-auto 仅用于零配置:确定目标平台后,安装对应的实际适配器,这样它会写入锁文件,并且你可以传入选项。
  • Cloudflare 上的服务端包大小:Workers 有大小限制。如果超出限制,请将大型库改为仅在客户端导入。
  • AWS / Node 18:SvelteKit v2 要求 Node 18.13+。较旧的 Node 版本会报出难以理解的错误。
  • ISR + 预渲染:对于设置了 export const prerender = true 的路由,ISR 不会生效。
  • adapter-cloudflare-workers 已弃用:请使用 @sveltejs/adapter-cloudflare(在 wrangler 配置中设置 assets.directory + assets.binding)。
  • Svelte 4 → 5:$app/stores 已弃用;请改用 $app/state。先更新 Svelte,再更新 SvelteKit。
  • Tailwind + <enhanced:img>:标签名选择器需要使用 enhanced\:img 转义冒号。
  • 聊天/类 SPA 界面需匹配 data-sveltekit-noscroll:默认的滚动到顶部行为可能会破坏无限滚动应用。
  • Vite 资源内联:小于 assetsInlineLimit(默认约 4kb)的资源会被内联为 base64。enhanced-img 不包含 svg。

常见问题

我应该使用 adapter-auto 吗? 原型开发时可以使用。选定目标平台后,请换成特定适配器,以便进行配置。

SPA 模式还是完整 SSR? 对于 SEO/性能,使用 adapter-static(预渲染)进行完整 SSR 是最佳选择。只有在必须部署到无法预渲染所有内容的纯静态托管平台时,才使用 SPA 回退模式。SPA 会损害 SEO 和性能。

什么时候应该进行预渲染? 对于每位访客看到的内容都相同的页面(营销页面、博客文章、文档),应进行预渲染。在路由中添加 export const prerender = true。

如何知道生产环境使用的是哪个适配器? adapter-auto 会在构建时记录它选择的适配器。否则,请查看 svelte.config.js。

多个适配器可以使用同一个 svelte.config.js 吗? 不可以——每个适配器都必须单独运行一次 vite build。常见的 CI 模式是为每个目标平台设置构建矩阵。

为什么我的 Cloudflare Worker 这么大? 这是包体积膨胀导致的——服务端导入会引入大型依赖。请将它们改为动态 import() 或仅在客户端导入。

SvelteKit 2 需要 Svelte 5 吗? 你需要 Svelte 4+。推荐使用 Svelte 5,以便使用 $app/state 和符文。

示例与参考

示例
文件涵盖内容
examples/build-preview.mdvite build、vite preview、构建时的环境变量
examples/adapter-node.md开发/构建/部署、自定义服务、环境变量
examples/adapter-static.md预渲染全部页面、SPA 回退、GitHub Pages
examples/adapter-cloudflare.mdworkers、pages、运行时 API、环境变量
examples/adapter-netlify.md部署、边缘函数、环境变量
examples/adapter-vercel.md部署、图像优化、ISR、环境变量、版本偏差保护
examples/writing-adapter.md使用 builder API 编写自定义适配器
examples/advanced-routing.mdrest 参数、可选参数、匹配器、排序、编码
examples/advanced-layouts.md嵌套布局、命名布局、错误重置、分组
examples/performance.md代码拆分、资源优化、水合优化
examples/images.mdenhanced-img、动态 CDN 加载、最佳实践
examples/accessibility.md路由播报、焦点管理、lang 属性
examples/seo.mdmeta 标签、OG 标签、JSON-LD、站点地图
examples/debugging.mdVS Code launch.json、浏览器断点
examples/migration-v2.md错误/重定向变更、Cookie 路径、顶层 Promise
参考资料
文件涵盖内容
references/adapters-comparison.md各适配器的详细适用场景对比表
references/building-reference.mdvite build 选项、预览、环境变量
references/routing-advanced-reference.mdrest/可选参数/匹配器/排序/编码深入解析
references/layouts-advanced-reference.md嵌套/命名/分组布局、重置、跳出布局
references/auth-reference.md会话与令牌、集成点、库
references/performance-reference.md完整的优化清单
references/images-reference.mdVite + @sveltejs/enhanced-img 参考
references/a11y-reference.md无障碍模式与资源
references/seo-reference.mdSEO 设置、meta 标签、结构化数据
references/migration-v1-v2-reference.md完整的破坏性变更列表
references/migration-sapper-reference.md完整的 Sapper → SvelteKit 迁移指南
references/debugging-reference.mdIDE/调试器配置

评论

支持 Markdown