` 不再需要。
### src/node_modules
Sapper 应用中的一个常见模式是将内部库放在 `src/node_modules` 目录中。这在 Vite 中不起作用,所以我们改用 [`src/lib`]($lib)。
## 页面和布局
### 重命名文件
现在路由仅由文件夹名称构成以消除歧义,通向 `+page.svelte` 的文件夹名称对应于路由。查看[路由文档](routing)了解概述。以下是旧文件和新文件的对比:
| 旧 | 新 |
| ------------------------- | ------------------------- |
| routes/about/index.svelte | routes/about/+page.svelte |
| routes/about.svelte | routes/about/+page.svelte |
您的自定义错误页面组件应从 `_error.svelte` 重命名为 `+error.svelte`。任何 `_layout.svelte` 文件同样应重命名为 `+layout.svelte`。[其他文件将被忽略](routing#Other-files)。
### 引入
从 `@sapper/app` 导入的 `goto`、`prefetch` 和 `prefetchRoutes` 应分别替换为从 [`$app/navigation`]($app-navigation) 导入的 `goto`、`preloadData` 和 `preloadCode`。
从 `@sapper/app` 的 `stores` 导入应被替换 — 请参阅下面的[Stores (存储)](migrating#Pages-and-layouts-Stores)部分。
之前从 `src/node_modules` 目录中导入的任何文件现在需要用 [`$lib`]($lib) 导入替换。
### Preload
如之前一样,页面和布局可以导出一个函数,该函数允许在渲染发生之前加载数据。
此函数名称从 `preload` 重命名为 [`load`](load),现在它位于紧邻其 `+page.svelte`(或 `+layout.svelte`)的 `+page.js`(或 `+layout.js`)中,且其 API 已更改。不再是两个参数 — `page` 和 `session` — 而是一个单一的 `event` 参数。
不再有 `this` 对象,因此也没有 `this.fetch`、`this.error` 或 `this.redirect`。取而代之的是,您可以从输入方法中获取 [`fetch`](load#Making-fetch-requests),[`error`](load#Errors) 和 [`redirect`](load#Redirects) 现在通过抛出实现。
### 存储 (Stores)
在 Sapper 中,您可以这样获取提供的存储的引用:
```js
// @filename: ambient.d.ts
declare module '@sapper/app';
// @filename: index.js
// ---cut---
import { stores } from '@sapper/app';
const { preloading, page, session } = stores();
```
`page` 存储仍然存在;`preloading` 被替换为具有 `from` 和 `to` 属性的 `navigating` 存储。`page` 现在有 `url` 和 `params` 属性,但没有 `path` 或 `query`。
在 SvelteKit 中访问它们的方式有所不同。`stores` 现在是 `getStores`,但在大多数情况下,这是不必要的,因为您可以直接从 [`$app/stores`]($app-stores) 导入 `navigating` 和 `page`。如果您使用的是 Svelte 5 和 SvelteKit 2.12 或更高版本,请考虑使用 [`$app/state`]($app-state)。
### 路由 (Routing)
不再支持正则路由。取而代之的是使用[高级路由匹配](advanced-routing#Matching)。
### 段 (Segments)
以前,布局组件会接收一个 `segment` 属性,指示子段。这已被移除;您应该使用更灵活的 `$page.url.pathname`(或 `page.url.pathname`)值来派生您感兴趣的段。
### URL
在 Sapper 中,所有相对 URL 都是相对于基本 URL 解析的 — 通常是 `/`,除非使用了 `basepath` 选项 — 而不是相对于当前页面。
这导致了一些问题,现在在 SvelteKit 中不再这样了。相对 URL 是相对于当前页面解析的(对于 `load` 函数中的 `fetch` URL,解析为目标页面)。在大多数情况下,使用根相对 URL(即以 `/` 开头)更简单,因为它们的意义不依赖于上下文。
### <a> 属性
- `sapper:prefetch` 现在是 `data-sveltekit-preload-data`
- `sapper:noscroll` 现在是 `data-sveltekit-noscroll`
## 端点 (Endpoints)
在 Sapper 中,[服务端路由](routing#server) 接收由 Node 的 `http` 模块暴露的 `req` 和 `res` 对象(或由框架如 Polka 和 Express 提供增强的版本)。
SvelteKit 被设计成可以与应用运行的环境无关 — 它可以运行在 Node 服务端,也可以运行在无服务端平台或 Cloudflare Worker 中。因此,您不能再直接与 `req` 和 `res` 交互。您的端点需要更新以符合新签名。
为了支持这种与环境无关的行为,`fetch` 现在在全局上下文中可用,因此不需要引入 `node-fetch`、`cross-fetch` 或类似的服务端 fetch 实现来使用它。
## 集成 (Integrations)
参阅[集成文档](./integrations)了解集成的详细信息。
### HTML 压缩器
Sapper 默认包含 `html-minifier`。SvelteKit 没有包含此功能,但您可以将其添加为生产依赖,然后通过[钩子](hooks#Server-hooks-handle)使用:
```js
// @filename: ambient.d.ts
///
declare module 'html-minifier';
// @filename: index.js
// ---cut---
import { minify } from 'html-minifier';
import { building } from '$app/environment';
const minification_options = {
collapseBooleanAttributes: true,
collapseWhitespace: true,
conservativeCollapse: true,
decodeEntities: true,
html5: true,
ignoreCustomComments: [/^#/],
minifyCSS: true,
minifyJS: false,
removeAttributeQuotes: true,
removeComments: false, // 一些 hydration 代码需要注释,所以保留它们
removeOptionalTags: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortAttributes: true,
sortClassName: true
};
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
let page = '';
return resolve(event, {
transformPageChunk: ({ html, done }) => {
page += html;
if (done) {
return building ? minify(page, minification_options) : page;
}
}
});
}
```
请注意,当使用 `vite preview` 测试生产构建的站点时,`prerendering` 为 `false`,因此要验证压缩效果,您需要直接检查生成的 HTML 文件。
# 额外资源
## 常见问题
请查看 [SvelteKit 常见问题](faq) 以获取常见问题的解决方案以及有用的提示和技巧。
对于源自这些库的问题,[Svelte 常见问题](../svelte/faq) 和 [`vite-plugin-svelte` 常见问题](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md) 也可能会有帮助。
## 示例
我们编写并发布了几个不同的 SvelteKit 站点作为示例:
- [`sveltejs/realworld`](https://github.com/sveltejs/realworld) 包含一个示例博客网站
- [HackerNews 克隆版](https://github.com/sveltejs/sites/tree/master/sites/hn.svelte.dev)
- [`svelte.dev`](https://github.com/sveltejs/svelte.dev)
SvelteKit 用户也在 GitHub 上发布了大量示例,可以在 [#sveltekit](https://github.com/topics/sveltekit) 和 [#sveltekit-template](https://github.com/topics/sveltekit-template) 主题下找到,以及在 [Svelte Society 网站](https://sveltesociety.dev/templates?category=sveltekit) 上找到。请注意,这些示例未经维护人员审核,可能不是最新的。
## 支持
您可以在 [Discord](/chat) 和 [StackOverflow](https://stackoverflow.com/questions/tagged/sveltekit) 上寻求帮助。为了尊重他人的时间,请首先在常见问题、Google 或其他搜索引擎、issue tracker 和 Discord 聊天历史记录中搜索与您的问题相关的信息。提问的人远多于回答的人,这将有助于社区以可扩展的方式成长。
# 术语表
SvelteKit 的核心提供了一个高度可配置的渲染引擎。本节描述了在讨论渲染时使用的一些术语。上述文档中提供了设置这些选项的参考。
## CSR
客户端渲染(CSR)是使用 JavaScript 在 web 浏览器中生成页面内容。
在 SvelteKit 中,默认会使用客户端渲染,但您可以通过[`csr = false` 页面选项](page-options#csr)关闭 JavaScript。
## 水合(Hydration)
Svelte 组件存储一些状态,并在状态更新时更新 DOM。在 SSR 期间获取数据时,SvelteKit 默认会存储这些数据,并将其与服务端渲染的 HTML 一起传输到客户端。然后,组件可以使用该数据在客户端上初始化,而无需再次调用相同的 API 端点。Svelte 随后会检查 DOM 是否处于预期状态,并在一个称为水合的过程中添加事件监听器。一旦组件完全水合,它们就可以像任何新创建的 Svelte 组件一样对其属性的变化做出反应。
在 SvelteKit 中,页面默认会被水合,但您可以通过[`csr = false` 页面选项](page-options#csr)关闭 JavaScript。
## 预渲染(Prerendering)
预渲染意味着在构建时计算页面内容并保存 HTML 以供显示。这种方法具有与传统服务端渲染页面相同的优势,但避免了为每个访问者重新计算页面,因此随着访问者数量的增加,几乎可以免费扩展。权衡之处在于构建过程更加耗费资源,并且预渲染的内容只能通过构建和部署应用程序的新版本来更新。
并非所有页面都可以预渲染。基本规则是:要使内容可预渲染,任何两个直接访问它的用户必须从服务端获得相同的内容,并且页面不能包含 [actions](form-actions)。请注意,只要所有用户都会看到相同的预渲染内容,您仍然可以预渲染基于页面参数加载的内容。
预渲染的页面并不限于静态内容。如果用户特定的数据是在客户端获取和渲染的,您可以构建个性化页面。这受制于上述不做 SSR 的内容的缺点。
在 SvelteKit 中,您可以通过[`prerender` 页面选项](page-options#prerender)和 `svelte.config.js` 中的 [`prerender` 配置](configuration#prerender)控制预渲染。
## 路由(Routing)
默认情况下,当您导航到新页面时(通过点击链接或使用浏览器的前进或后退按钮),SvelteKit 将拦截尝试的导航,而不是允许浏览器向服务端发送目标页面的请求。然后,SvelteKit 将通过渲染新页面的组件来更新客户端显示的内容,这反过来可以调用必要的 API 端点。这种根据尝试的导航在客户端更新页面的过程称为客户端路由。
在 SvelteKit 中,默认会使用客户端路由,但您可以通过 [`data-sveltekit-reload`](link-options#data-sveltekit-reload) 跳过它。
## SPA
单页应用(SPA)是一种应用程序,其中所有对服务端的请求都加载单个 HTML 文件,然后根据请求的 URL 对请求的内容进行客户端渲染。所有导航都在客户端处理,这个过程称为客户端路由,每页内容都会更新,而常见的布局元素基本保持不变。SPA 不提供 SSR,这具有上述缺点。然而,某些应用程序不会受到这些缺点的重大影响,比如登录后的复杂业务应用程序,在这种情况下 SEO 不重要,并且已知用户将从一致的计算环境访问应用程序。
在 SvelteKit 中,您可以[使用 `adapter-static` 构建 SPA](single-page-apps)。
## SSG
静态站点生成(SSG)是指每个页面都预渲染的站点。SvelteKit 不是为仅做静态站点生成而构建的,因此在高效渲染大量页面方面可能不如专门为此目的构建的工具。然而,与大多数专门构建的 SSG 相比,SvelteKit 确实很好地允许在不同页面上混合和匹配不同的渲染类型。完全预渲染站点的一个好处是您不需要维护或支付服务端来执行 SSR。一旦生成,站点就可以从 CDN 提供服务,从而带来出色的"首字节时间"性能。这种交付模型通常被称为 JAMstack。
在 SvelteKit 中,您可以通过使用 [`adapter-static`](adapter-static) 或通过使用[`prerender` 页面选项](page-options#prerender)或 `svelte.config.js` 中的 [`prerender` 配置](configuration#prerender)配置每个页面预渲染来进行静态站点生成。
## SSR
服务端渲染(SSR)是在服务端上生成页面内容。SSR 通常是 SEO 的首选。虽然一些搜索引擎可以索引在客户端动态生成的内容,但在这些情况下可能需要更长的时间。它还倾向于提高感知性能,并使您的应用程序在 JavaScript 失败或被禁用时对用户可访问(这种情况[发生的频率可能比您想象的要高](https://kryogenix.org/code/browser/everyonehasjs.html))。
在 SvelteKit 中,页面默认是服务端渲染的。您可以通过[`ssr` 页面选项](page-options#ssr)禁用 SSR。
# @sveltejs/kit
```js
// @noErrors
import {
Server,
VERSION,
error,
fail,
isActionFailure,
isHttpError,
isRedirect,
json,
redirect,
text
} from '@sveltejs/kit';
```
## Server
```dts
class Server {/*…*/}
```
```dts
constructor(manifest: SSRManifest);
```
```dts
init(options: ServerInitOptions): Promise
;
```
```dts
respond(request: Request, options: RequestOptions): Promise
;
```
## VERSION
```dts
const VERSION: string;
```
## error
抛出一个带有 HTTP 状态码和可选消息的错误。在请求处理期间调用时,这将导致 SvelteKit 返回一个错误响应而不会调用 `handleError`。
确保您没有捕获抛出的错误,否则会阻止 SvelteKit 处理它。
```dts
function error(status: number, body: App.Error): never;
```
```dts
function error(
status: number,
body?: {
message: string;
} extends App.Error
? App.Error | string | undefined
: never
): never;
```
## fail
创建一个 `ActionFailure` 对象。
```dts
function fail(status: number): ActionFailure;
```
```dts
function fail<
T extends Record | undefined = undefined
>(status: number, data: T): ActionFailure;
```
## isActionFailure
检查这是否是由 `fail` 抛出的 action 失败。
```dts
function isActionFailure(e: unknown): e is ActionFailure;
```
## isHttpError
检查这是否是由 `error` 抛出的错误。
```dts
function isHttpError(
e: unknown,
status?: T | undefined
): e is HttpError_1 & {
status: T extends undefined ? never : T;
};
```
## isRedirect
检查这是否是由 `redirect` 抛出的重定向。
```dts
function isRedirect(e: unknown): e is Redirect_1;
```
## json
从提供的数据创建一个 JSON `Response` 对象。
```dts
function json(
data: any,
init?: ResponseInit | undefined
): Response;
```
## redirect
重定向一个请求。在请求处理期间调用时,SvelteKit 将返回一个重定向响应。确保您没有捕获抛出的重定向,否则会阻止 SvelteKit 处理它。
```dts
function redirect(
status:
| 300
| 301
| 302
| 303
| 304
| 305
| 306
| 307
| 308
| ({} & number),
location: string | URL
): never;
```
## text
从提供的正文创建一个 `Response` 对象。
```dts
function text(
body: string,
init?: ResponseInit | undefined
): Response;
```
## Action
位于 `+page.server.js` 的 `export const actions = {..}` 中的表单 action 方法的形状。
更多信息请参见 [表单 action ](/docs/kit/form-actions)。
```dts
type Action<
Params extends Partial
> = Partial<
Record
>,
OutputData extends Record | void = Record<
string,
any
> | void,
RouteId extends string | null = string | null
> = (
event: RequestEvent
) => MaybePromise;
```
## ActionFailure
```dts
interface ActionFailure<
T extends Record
| undefined = undefined
> {/*…*/}
```
```dts
status: number;
```
```dts
[uniqueSymbol]: true;
```
## ActionResult
通过 `fetch` 调用表单 action 时,响应将具有以下形状之一。
```svelte
` 元素。
`submit` 函数在提交时会被调用,传入给定的 FormData 和应该触发的 `action`。如果调用 `cancel`,表单将不会被提交。
您可以使用 abort `controller` 在另一个提交开始时取消当前提交。
如果返回一个函数,则该函数将被调用,并传入来自服务端的响应。如果没有返回任何内容,将使用后备处理。
如果未设置此函数或其返回值,它将:
- 如果 action 与表单在相同的页面上,则回退到使用返回的数据更新 `form` prop
- 更新 `page.status`
- 重置 `` 元素并在成功提交且没有重定向响应的情况下使所有数据失效。
- 在有重定向响应的情况下进行重定向
- 在出现意外错误时重定向到最近的错误页面
如果您提供了带有回调的自定义函数并想使用默认行为,请在回调中调用 `update`。
```dts
function enhance<
Success extends Record | undefined,
Failure extends Record | undefined
>(
form_element: HTMLFormElement,
submit?: import('@sveltejs/kit').SubmitFunction<
Success,
Failure
>
): {
destroy(): void;
};
```
# $app/navigation
```js
// @noErrors
import {
afterNavigate,
beforeNavigate,
disableScrollHandling,
goto,
invalidate,
invalidateAll,
onNavigate,
preloadCode,
preloadData,
pushState,
replaceState
} from '$app/navigation';
```
## afterNavigate
一个生命周期函数,在当前组件挂载时以及每当我们导航到新的 URL 时,运行提供的 `callback`。
`afterNavigate` 必须在组件初始化期间调用。只要组件保持挂载状态,它就会一直处于活动状态。
```dts
function afterNavigate(
callback: (
navigation: import('@sveltejs/kit').AfterNavigate
) => void
): void;
```
## beforeNavigate
一个导航拦截器,在我们导航到一个 URL 之前触发,无论是通过点击链接、调用 `goto(...)`还是使用浏览器的前进/后退控件。
调用 `cancel()` 将阻止导航完成。如果 `navigation.type === 'leave'` — 意味着用户正在离开应用(或关闭标签页)— 调用 `cancel` 将触发原生浏览器的卸载确认对话框。在这种情况下,导航可能会被取消,也可能不会,取决于用户的响应。
当导航到不是 SvelteKit 拥有的路由时(因此由 SvelteKit 的客户端路由器控制),`navigation.to.route.id` 将为 `null`。
如果导航将(如果不取消)导致文档卸载 — 换句话说,'leave' 导航和 `navigation.to.route === null` 的 'link' 导航 — `navigation.willUnload` 为 `true`。
`beforeNavigate` 必须在组件初始化期间调用。只要组件保持挂载状态,它就会一直处于活动状态。
```dts
function beforeNavigate(
callback: (
navigation: import('@sveltejs/kit').BeforeNavigate
) => void
): void;
```
## disableScrollHandling
如果在导航后页面更新时调用(例如在 `onMount` 或 `afterNavigate` 或 action 中),这将禁用 SvelteKit 的内置滚动处理。
这通常不建议使用,因为它会破坏用户的预期行为。
```dts
function disableScrollHandling(): void;
```
## goto
允许您以编程方式导航到给定的路由,并提供诸如保持当前元素焦点等选项。
返回一个 Promise,当 SvelteKit 导航(或导航失败,在这种情况下 promise 会 reject)到指定的 `url` 时 resolve。
对于外部 URL,请使用 `window.location = url` 而不是调用 `goto(url)`。
```dts
function goto(
url: string | URL,
opts?:
| {
replaceState?: boolean | undefined;
noScroll?: boolean | undefined;
keepFocus?: boolean | undefined;
invalidateAll?: boolean | undefined;
state?: App.PageState | undefined;
}
| undefined
): Promise;
```
## invalidate
如果当前活动页面的任何 `load` 函数通过 `fetch` 或 `depends` 依赖于相关的 `url`,则会导致这些函数重新运行。返回一个 Promise,在页面随后更新时 resolve。
如果参数以 `string` 或 `URL` 形式给出,它必须解析为传递给 `fetch` 或 `depends` 的相同 URL(包括查询参数)。
要创建自定义标识符,请使用以 `[a-z]+:` 开头的字符串(例如 `custom:state`)— 这是一个有效的 URL。
`function` 参数可用于定义自定义谓词。它接收完整的 `URL` 并在返回 `true` 时导致 `load` 重新运行。
如果您想基于模式而不是精确匹配来使无效化,这很有用。
```ts
// 示例:匹配 '/path',不考虑查询参数
import { invalidate } from '$app/navigation';
invalidate((url) => url.pathname === '/path');
```
```dts
function invalidate(
resource: string | URL | ((url: URL) => boolean)
): Promise;
```
## invalidateAll
导致当前活动页面的所有 `load` 函数重新运行。返回一个 Promise,在页面随后更新时 resolve。
```dts
function invalidateAll(): Promise;
```
## onNavigate
一个生命周期函数,在我们导航到新的 URL 之前立即运行提供的 `callback`,但在完整页面导航期间除外。
如果您返回一个 `Promise`,SvelteKit 将等待它 resolve 后才完成导航。这允许您 — 例如 — 使用 `document.startViewTransition`。避免使用解析较慢的 promise,因为导航会显得停滞不前。
如果从回调返回一个函数(或 resolve 为函数的 `Promise`),它将在 DOM 更新后被调用。
`onNavigate` 必须在组件初始化期间调用。只要组件保持挂载状态,它就会一直保持活动状态。
```dts
function onNavigate(
callback: (
navigation: import('@sveltejs/kit').OnNavigate
) => MaybePromise<(() => void) | void>
): void;
```
## preloadCode
以编程方式导入尚未获取的路由的代码。通常,您可能会调用这个来加速后续导航。
您可以通过任何匹配的路径名指定路由,如 `/about`(匹配 `src/routes/about/+page.svelte`)或 `/blog/*`(匹配 `src/routes/blog/[slug]/+page.svelte`)。
与 `preloadData` 不同,这不会调用 `load` 函数。返回一个 Promise,在模块导入完成时 resolves。
```dts
function preloadCode(pathname: string): Promise;
```
## preloadData
以编程方式预加载给定页面,这意味着
1. 确保页面的代码已加载,并且
2. 调用页面 load 函数并传入适当的选项。
这与 SvelteKit 在用户点击或将鼠标悬停在带有 `data-sveltekit-preload-data` 的 `` 元素上时触发的行为相同。
如果下一次导航是到 `href`,将使用从 load 返回的值,使导航变得即时。
返回一个 Promise,在预加载完成后,它将 resolve 为运行新路由的 `load` 函数的结果。
```dts
function preloadData(href: string): Promise<
| {
type: 'loaded';
status: number;
data: Record;
}
| {
type: 'redirect';
location: string;
}
>;
```
## pushState
以编程方式使用给定的 `page.state` 创建新的历史条目。要使用当前 URL,您可以将 `''` 作为第一个参数传递。用于[浅层路由](/docs/kit/shallow-routing)。
```dts
function pushState(
url: string | URL,
state: App.PageState
): void;
```
## replaceState
以编程方式用给定的 `page.state` 替换当前历史条目。要使用当前 URL,您可以将 `''` 作为第一个参数传递。用于[浅层路由](/docs/kit/shallow-routing)。
```dts
function replaceState(
url: string | URL,
state: App.PageState
): void;
```
# $app/paths
```js
// @noErrors
import { assets, base, resolveRoute } from '$app/paths';
```
## assets
一个匹配 [`config.kit.paths.assets`](/docs/kit/configuration#paths)的绝对路径。
> [!NOTE] 如果指定了 `config.kit.paths.assets` 的值,它将在 `vite dev` 或 `vite preview` 期间被替换为 `'/_svelte_kit_assets'`,因为资源还没有位于它们最终的 URL 上。
```dts
let assets:
| ''
| `https://${string}`
| `http://${string}`
| '/_svelte_kit_assets';
```
## base
一个匹配 [`config.kit.paths.base`](/docs/kit/configuration#paths) 的字符串。
使用示例:`链接`
```dts
let base: '' | `/${string}`;
```
## resolveRoute
使用参数填充路由 ID 以解析路径名。
```js
// @errors: 7031
import { resolveRoute } from '$app/paths';
resolveRoute(`/blog/[slug]/[...somethingElse]`, {
slug: 'hello-world',
somethingElse: 'something/else'
}); // `/blog/hello-world/something/else`
```
```dts
function resolveRoute(
id: string,
params: Record
): string;
```
# $app/server
```js
// @noErrors
import { read } from '$app/server';
```
## read
从 2.4.0 版本开始可用
从文件系统中读取导入资源的内容
```js
// @errors: 7031
import { read } from '$app/server';
import somefile from './somefile.txt';
const asset = read(somefile);
const text = await asset.text();
```
```dts
function read(asset: string): Response;
```
# $app/state
SvelteKit 通过 `$app/state` 模块提供了三个只读状态对象 — `page`、`navigating` 和 `updated`。
> [!NOTE]
> 此模块在 2.12 版本中添加。如果您使用的是早期版本的 SvelteKit,请使用 [`$app/stores`]($app-stores)。
```js
// @noErrors
import { navigating, page, updated } from '$app/state';
```
## navigating
一个表示正在进行的导航的只读对象,具有 `from`、`to`、`type` 和(如果 `type === 'popstate'`)`delta` 属性。
当没有导航发生时或在服务端渲染期间,这些值为 `null`。
```dts
const navigating:
| import('@sveltejs/kit').Navigation
| {
from: null;
to: null;
type: null;
willUnload: null;
delta: null;
complete: null;
};
```
## page
一个包含当前页面信息的响应式对象,用于以下几个用途:
- 在组件树的任何位置检索所有页面/布局的组合 `data`(另见 [加载数据](/docs/kit/load))
- 在组件树的任何位置检索 `form` prop 的当前值(另见 [表单 actions](/docs/kit/form-actions))
- 检索通过 `goto`、`pushState` 或 `replaceState` 设置的页面状态(另见 [goto](/docs/kit/$app-navigation#goto) 和 [浅路由](/docs/kit/shallow-routing))
- 检索元数据,如当前 URL、当前路由及其参数,以及是否发生错误
```svelte
当前位置 {page.url.pathname}
{#if page.error}
检测到问题
{:else}
所有系统正常运行
{/if}
```
在服务端,值只能在渲染期间读取(换句话说,不能在如 `load` 函数等中读取)。在浏览器中,可以随时读取这些值。
```dts
const page: import('@sveltejs/kit').Page;
```
## updated
一个初始值为 `false` 的响应式只读值。如果 [`version.pollInterval`](/docs/kit/configuration#version) 设置为非零值,SvelteKit 将轮询检查应用程序的新版本,当检测到新版本时,将 `current` 更新为 `true`。无论是否轮询,`updated.check()` 都将强制立即检查。
```dts
const updated: {
get current(): boolean;
check(): Promise;
};
```
# $app/stores
此模块包含从 [`$app/state`]($app-state) 导出的基于 store 的等价物。如果您使用的是 SvelteKit 2.12 或更高版本,请使用该模块代替。
```js
// @noErrors
import { getStores, navigating, page, updated } from '$app/stores';
```
## getStores
```dts
function getStores(): {
page: typeof page;
navigating: typeof navigating;
updated: typeof updated;
};
```
## 导航
请改用 `$app/state` 中的 `navigating`(需要 Svelte 5,[查看更多信息](/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
一个可读 store。当导航开始时,其值为一个具有 `from`、`to`、`type` 和(如果 `type === 'popstate'`)`delta` 属性的 `Navigation` 对象。当导航结束时,其值恢复为 `null`。
在服务端上,此 store 只能在组件初始化期间被订阅。在浏览器中,它可以在任何时候被订阅。
```dts
const navigating: import('svelte/store').Readable<
import('@sveltejs/kit').Navigation | null
>;
```
## page
请改用 `$app/state` 中的 `page`(需要 Svelte 5,[查看更多信息](/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
一个可读 store ,其值包含页面数据。
在服务端上,此 store 只能在组件初始化期间被订阅。在浏览器中,它可以在任何时候被订阅。
```dts
const page: import('svelte/store').Readable<
import('@sveltejs/kit').Page
>;
```
## updated
请改用 `$app/state` 中的 `updated`(需要 Svelte 5,[查看更多信息](/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
一个可读 store ,其初始值为 `false`。如果 [`version.pollInterval`](/docs/kit/configuration#version) 为非零值,SvelteKit 将轮询应用程序的新版本,并在检测到新版本时将 store 值更新为 `true`。无论是否轮询,`updated.check()` 都将强制立即检查。
在服务端上,此 store 只能在组件初始化期间被订阅。在浏览器中,它可以在任何时候被订阅。
```dts
const updated: import('svelte/store').Readable & {
check(): Promise;
};
```
# $env/dynamic/private
此模块提供对运行时环境变量的访问,这些变量由您运行的平台定义。例如,如果您使用 [`adapter-node`](https://github.com/sveltejs/kit/tree/main/packages/adapter-node)(或运行 [`vite preview`](/docs/kit/cli)),这相当于 `process.env`。此模块只包含*不*以 [`config.kit.env.publicPrefix`](/docs/kit/configuration#env) 开头且*确实*以 [`config.kit.env.privatePrefix`](/docs/kit/configuration#env)(如果配置了)开头的变量。
此模块不能导入到客户端代码中。
动态环境变量不能在预渲染期间使用。
```ts
import { env } from '$env/dynamic/private';
console.log(env.DEPLOYMENT_SPECIFIC_VARIABLE);
```
> 在 `dev` 环境中,`$env/dynamic` 始终包含来自 `.env` 的环境变量。在 `prod` 环境中,这种行为将取决于您使用的适配器。
# $env/dynamic/public
类似于 [`$env/dynamic/private`](/docs/kit/$env-dynamic-private) ,但只包含以 [`config.kit.env.publicPrefix`](/docs/kit/configuration#env)(默认为 `PUBLIC_`)开头的变量,因此可以安全地暴露给客户端代码。
请注意,所有公共动态环境变量都必须从服务端发送到客户端,这会导致更大的网络请求 — 如果可能的话,请使用 `$env/static/public` 代替。
动态环境变量不能在预渲染期间使用。
```ts
import { env } from '$env/dynamic/public';
console.log(env.PUBLIC_DEPLOYMENT_SPECIFIC_VARIABLE);
```
# $env/static/private
由 Vite 从 `.env` 文件和 `process.env` [加载的环境变量](https://vitejs.dev/guide/env-and-mode.html#env-files)。与 [`$env/dynamic/private`](/docs/kit/$env-dynamic-private) 类似,此模块不能导入到客户端代码中。此模块仅包含*不*以 [`config.kit.env.publicPrefix`](/docs/kit/configuration#env) 开头,且*确实*以 [`config.kit.env.privatePrefix`](/docs/kit/configuration#env) 开头的变量(如果已配置)。
_与_ [`$env/dynamic/private`](/docs/kit/$env-dynamic-private) _不同_,从此模块导出的值在构建时被静态注入到您的代码包中,这使得可以进行死代码消除等优化。
```ts
import { API_KEY } from '$env/static/private';
```
请注意,您的代码中引用的所有环境变量都应该被声明(例如在 `.env` 文件中),即使它们在应用程序部署时才有值:
```
MY_FEATURE_FLAG=""
```
您可以通过命令行覆盖 `.env` 的值,如下所示:
```bash
MY_FEATURE_FLAG="enabled" npm run dev
```
# $env/static/public
类似于 [`$env/static/private`](/docs/kit/$env-static-private),但它只包含以 [`config.kit.env.publicPrefix`](/docs/kit/configuration#env)(默认为 `PUBLIC_`)开头的环境变量,因此可以安全地暴露给客户端代码。
这些值在构建时会被静态替换。
```ts
import { PUBLIC_BASE_URL } from '$env/static/public';
```
# $lib
SvelteKit 自动使用 `$lib` 导入别名,使 `src/lib` 下的文件可用。您可以在您的[配置文件](configuration#files)中更改此别名指向的目录。
```svelte
一个可重用的组件
```
```svelte
```
# $service-worker
```js
// @noErrors
import { base, build, files, prerendered, version } from '$service-worker';
```
此模块仅在 [service workers](/docs/kit/service-workers) 中可用。
## base
部署的 `base` 路径。通常这等同于 `config.kit.paths.base`,但它是从 `location.pathname` 计算得出的,这意味着即使网站部署到子目录中,它也能正常工作。
注意这里有 `base` 但没有 `assets`,因为当指定了 `config.kit.paths.assets` 时不能使用 service workers。
```dts
const base: string;
```
## build
一个由 Vite 生成的文件的 URL 字符串数组,适合用 `cache.addAll(build)` 进行缓存。在开发过程中,这是一个空数组。
```dts
const build: string[];
```
## files
一个由静态目录(或由 `config.kit.files.assets` 指定的任何目录)中的文件的 URL 字符串数组。您可以使用 [`config.kit.serviceWorker.files`](/docs/kit/configuration) 自定义 `static` 目录包含的文件。
```dts
const files: string[];
```
## prerendered
一个对应于预渲染页面和端点的路径名数组。在开发过程中,这是一个空数组。
```dts
const prerendered: string[];
```
## version
参见[`config.kit.version`](/docs/kit/configuration#version)。它在 service workers 内生成唯一的缓存名称时很有用,这样您的应用程序的后续部署可以使旧的缓存失效。
```dts
const version: string;
```
# 配置
您的项目配置位于项目根目录下的 `svelte.config.js` 文件中。除了 SvelteKit 外,此配置对象还被其他与 Svelte 集成的工具(如编辑器扩展)使用。
```js
/// 文件: svelte.config.js
// @文件名: ambient.d.ts
declare module '@sveltejs/adapter-auto' {
const plugin: () => import('@sveltejs/kit').Adapter;
export default plugin;
}
// @文件名: index.js
// ---切割---
import adapter from '@sveltejs/adapter-auto';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter()
}
};
export default config;
```
## 配置
```dts
interface Config {/*…*/}
```
```dts
compilerOptions?: CompileOptions;
```
- 默认 `{}`
传递给 [`svelte.compile`](/docs/svelte/svelte-compiler#CompileOptions) 的选项。
```dts
extensions?: string[];
```
- 默认 `[".svelte"]`
应视为 Svelte 文件的文件扩展名列表。
```dts
kit?: KitConfig;
```
SvelteKit 配置选项
```dts
preprocess?: any;
```
预处理选项(如果有)。预处理也可以通过 Vite 的预处理功能实现。
```dts
vitePlugin?: PluginOptions;
```
`vite-plugin-svelte` 插件选项。
```dts
[key: string]: any;
```
任何需要 Svelte 集成工具的额外选项。
## KitConfig
`kit` 属性用于配置 SvelteKit,并可以具有以下属性:
## adapter
- 默认 `undefined`
当执行 `vite build` 时运行您的 [适配器](/docs/kit/adapters)。它决定如何将输出转换为适应不同平台的格式。
## alias
- 默认 `{}`
一个包含零个或多个别名的对象,用于替换 `import` 语句中的值。这些别名会自动传递给 Vite 和 TypeScript。
```js
// @errors: 7031
/// 文件: svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
alias: {
// 这将匹配一个文件
'my-file': 'path/to/my-file.js',
// 这将匹配一个目录及其内容
// (`my-directory/x` 解析到 `path/to/my-directory/x`)
'my-directory': 'path/to/my-directory',
// 以 /* 结尾的别名将只匹配目录中的内容,而不是目录本身
'my-directory/*': 'path/to/my-directory/*'
}
}
};
```
> [!注意] 内置的 `$lib` 别名由 `config.kit.files.lib` 控制,因为它用于打包。
> [!注意] 您需要运行 `npm run dev`,以便 SvelteKit 自动生成 `jsconfig.json` 或 `tsconfig.json` 中所需的别名配置。
## appDir
- 默认 `"_app"`
SvelteKit 存放其内容的目录,包括静态资源(如 JS 和 CSS)及内部使用的路由。
如果指定了 `paths.assets`,将有两个应用程序目录 —— `${paths.assets}/${appDir}` 和 `${paths.base}/${appDir}`。
## csp
[内容安全策略 (Content Security Policy)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) 配置。CSP 有助于保护您的用户免受跨站脚本 (XSS) 攻击,通过限制资源加载来源。例如,类似这样的配置……
```js
// @errors: 7031
/// 文件: svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
csp: {
directives: {
'script-src': ['self']
},
// 必须指定 `report-uri` 或 `report-to` 指令,或同时指定二者
reportOnly: {
'script-src': ['self'],
'report-uri': ['/']
}
}
}
};
export default config;
```
……将阻止从外部网站加载脚本。SvelteKit 将为它生成的任何内联样式和脚本添加 nonce 或哈希(取决于 `mode`)。
要为手动包含在 `src/app.html` 中的脚本和链接添加 nonce,可以使用占位符 `%sveltekit.nonce%` (例如 `
```
如果将 `pollInterval` 设置为非零值,SvelteKit 将在后台轮询新版本,并在检测到时将 [`updated.current`](/docs/kit/$app-state#updated) 的值设置为 `true`。
```ts
// @noErrors
name?: string;
```
当前应用程序版本字符串。如果指定,必须是确定性的(例如提交引用,而不是 `Math.random()` 或 `Date.now().toString()`),否则默认为构建的时间戳。
例如,要使用当前的提交哈希,您可以通过 `git rev-parse HEAD`:
```js
// @errors: 7031
/// file: svelte.config.js
import * as child_process from 'node:child_process';
export default {
kit: {
version: {
name: child_process.execSync('git rev-parse HEAD').toString().trim()
}
}
};
```
```ts
// @noErrors
pollInterval?: number;
```
- 默认 `0`
轮询版本变化的时间间隔(单位:毫秒)。如果设置为 `0`,则不会进行轮询。
# 命令行界面
SvelteKit 项目使用 [Vite](https://vitejs.dev),这意味着您将主要使用其 CLI(通过 `npm run dev/build/preview` 脚本):
- `vite dev` — 启动开发服务端
- `vite build` — 构建应用程序的生产版本
- `vite preview` — 在本地运行生产版本
但是 SvelteKit 包含自己的命令行界面,用于初始化您的项目:
## svelte-kit sync
`svelte-kit sync` 为您的项目创建 `tsconfig.json` 和所有生成的类型(您可以在路由文件中以 `./$types` 的形式导入)。当您创建一个新项目时,它会被列为 `prepare` 脚本,并且会作为 npm 生命周期的一部分自动运行,所以您通常不需要手动运行这个命令。
# 类型
## 生成的类型
`RequestHandler` 和 `Load` 类型都接受一个 `Params` 参数,允许您为 `params` 对象定义类型。例如,这个端点需要 `foo`、`bar` 和 `baz` 参数:
```js
/// file: src/routes/[foo]/[bar]/[baz]/+page.server.js
// @errors: 2355 2322 1360
/** @type {import('@sveltejs/kit').RequestHandler<{
foo: string;
bar: string;
baz: string
}>} */
export async function GET({ params }) {
// ...
}
```
显然,这样编写很麻烦,而且不够灵活(如果您将 `[foo]` 目录重命名为 `[qux]`,类型将不再反映实际情况)。
为了解决这个问题,SvelteKit 为您的每个端点和页面生成 `.d.ts` 文件:
```ts
/// file: .svelte-kit/types/src/routes/[foo]/[bar]/[baz]/$types.d.ts
/// link: true
import type * as Kit from '@sveltejs/kit';
type RouteParams = {
foo: string;
bar: string;
baz: string;
};
export type PageServerLoad = Kit.ServerLoad;
export type PageLoad = Kit.Load;
```
这些文件可以作为同级文件导入到您的端点和页面中,这要归功于 TypeScript 配置中的 [`rootDirs`](https://www.typescriptlang.org/tsconfig#rootDirs) 选项:
```js
/// file: src/routes/[foo]/[bar]/[baz]/+page.server.js
// @filename: $types.d.ts
import type * as Kit from '@sveltejs/kit';
type RouteParams = {
foo: string;
bar: string;
baz: string;
}
export type PageServerLoad = Kit.ServerLoad;
// @filename: index.js
// @errors: 2355
// ---cut---
/** @type {import('./$types').PageServerLoad} */
export async function GET({ params }) {
// ...
}
```
```js
/// file: src/routes/[foo]/[bar]/[baz]/+page.js
// @filename: $types.d.ts
import type * as Kit from '@sveltejs/kit';
type RouteParams = {
foo: string;
bar: string;
baz: string;
}
export type PageLoad = Kit.Load;
// @filename: index.js
// @errors: 2355
// ---cut---
/** @type {import('./$types').PageLoad} */
export async function load({ params, fetch }) {
// ...
}
```
> [!NOTE] 要使此功能生效,您的 `tsconfig.json` 或 `jsconfig.json` 应该继承自生成的 `.svelte-kit/tsconfig.json`(其中 `.svelte-kit` 是您的 [`outDir`](configuration#outDir)):
>
> `{ "extends": "./.svelte-kit/tsconfig.json" }`
### 默认 tsconfig.json
生成的 `.svelte-kit/tsconfig.json` 文件包含多种选项。有些是根据您的项目配置以编程方式生成的,一般情况下不应该在没有充分理由的情况下覆盖:
```json
/// file: .svelte-kit/tsconfig.json
{
"compilerOptions": {
"baseUrl": "..",
"paths": {
"$lib": "src/lib",
"$lib/*": "src/lib/*"
},
"rootDirs": ["..", "./types"]
},
"include": ["../src/**/*.js", "../src/**/*.ts", "../src/**/*.svelte"],
"exclude": ["../node_modules/**", "./**"]
}
```
其他一些选项是 SvelteKit 正常工作所必需的,除非您知道自己在做什么,否则也不应该修改:
```json
/// file: .svelte-kit/tsconfig.json
{
"compilerOptions": {
// 这确保类型使用 `import type` 显式导入,
// 这是必需的,因为 svelte-preprocess
// 否则无法正确编译组件
"importsNotUsedAsValues": "error",
// Vite 一次编译一个 TypeScript 模块,
// 而不是编译整个模块图
"isolatedModules": true,
// TypeScript 无法'看到'您在标记中
// 何时使用导入的值,所以我们需要这个
"preserveValueImports": true,
// 这确保 `vite build` 和
// `svelte-package` 都能正常工作
"lib": ["esnext", "DOM", "DOM.Iterable"],
"moduleResolution": "node",
"module": "esnext",
"target": "esnext"
}
}
```
## $lib
这是一个指向 `src/lib` 的简单别名,或者指向在 [`config.kit.files.lib`](configuration#files) 中指定的任何目录。它允许您访问常用组件和实用工具模块,而无需使用 `../../../../` 这样的路径。
### $lib/server
`$lib` 的子目录。SvelteKit 会阻止您在客户端代码中导入 `$lib/server` 中的任何模块。参见[仅服务端模块](server-only-modules)。
## app.d.ts
`app.d.ts` 文件包含您的应用程序的环境类型,即无需显式导入就可以使用的类型。
这个文件中总是包含 `App` 命名空间。此命名空间包含几个影响您与某些 SvelteKit 功能交互的类型。
## Error
定义预期和非预期错误的通用形状。预期错误使用 `error` 函数抛出。非预期错误由 `handleError` 钩子处理,这些钩子应该返回这种形状。
```dts
interface Error {/*…*/}
```
```dts
message: string;
```
## Locals
定义 `event.locals` 的接口,可以在服务端[hooks](/docs/kit/hooks)(`handle` 和 `handleError`)、仅服务端的 `load` 函数和 `+server.js` 文件中访问。
```dts
interface Locals {}
```
## PageData
定义 [page.data state](/docs/kit/$app-state#page) 和 [$page.data store](/docs/kit/$app-stores#page) 的通用形状 - 即所有页面之间共享的数据。
`./$types` 中的 `Load` 和 `ServerLoad` 函数将相应地被收窄。
对于仅存在于特定页面上的数据,请使用可选属性。不要添加索引签名(`[key: string]: any`)。
```dts
interface PageData {}
```
## PageState
定义 `page.state` 对象的形状,可以使用 `$app/navigation` 中的 [`pushState`](/docs/kit/$app-navigation#pushState) 和 [`replaceState`](/docs/kit/$app-navigation#replaceState) 函数来操作。
```dts
interface PageState {}
```
## Platform
如果您的适配器通过 `event.platform` 提供[平台特定上下文](/docs/kit/adapters#Platform-specific-context),您可以在这里指定它。
```dts
interface Platform {}
```
# Start of the Svelte CLI documentation
# 概述
命令行接口 (CLI),`sv`,是一个用于创建和维护 Svelte 应用程序的工具包。
## 使用方法
运行 `sv` 最简单的方式是使用 [`npx`](https://docs.npmjs.com/cli/v8/commands/npx)(如果您使用其他包管理器,则使用相应的命令 — 例如,如果您使用 [pnpm](https://pnpm.io/),则使用 `pnpx`):
```bash
npx sv
```
如果您在一个已经安装了 `sv` 的项目中,它将使用本地安装的版本,否则它会下载最新版本并直接运行而无需安装,这对于 [`sv create`](sv-create) 特别有用。
## 致谢
感谢 [Christopher Brown](https://github.com/chbrown),他最初拥有 npm 上的 `sv` 名称,并慷慨地允许将其用于 Svelte CLI。您可以在 [`@chbrown/sv`](https://www.npmjs.com/package/@chbrown/sv) 找到原始的 `sv` 包。
# sv create
`sv create` 用于设置一个新的 SvelteKit 项目,可以选择[设置额外功能](sv-add#Official-add-ons)。
## 使用方法
```bash
npx sv create [options] [path]
```
## 选项
### `--template `
选择使用哪个项目模板:
- `minimal` — 为新应用提供的基础脚手架
- `demo` — 展示应用,包含一个无需 JavaScript 即可运行的猜词游戏
- `library` — 用于 Svelte 库的模板,使用 `svelte-package` 进行设置
### `--types