SvelteKit 是 Sapper 的继任者,并共享其设计中的许多元素。
如果您已经有一个计划迁移到 SvelteKit 的 Sapper 应用程序,您将需要做出一些更改。在迁移过程中查看一些示例可能会有所帮助。[一些示例](additional-resources#Examples)
## package.json
###
类型: "模块"
添加 `"类型": "模块"` 到您的 `package.json`。如果您使用的是 Sapper 0.29.3 或更高版本,您可以单独执行此步骤,作为增量迁移的一部分。
###
依赖关系
删除 `polka` 或 `express`,如果您使用其中之一,以及任何中间件,如 `sirv` 或 `compression`。
###
开发依赖项
删除您的 `devDependencies` 中的 `sapper`,并用 `@sveltejs/kit` 和您计划使用的任何 [适配器](adapters)(见 [下一节](migrating#Project-files-Configuration))替换。
###
脚本
任何引用 `sapper` 的脚本都需要更新:
* `` 使用 Node [适配器](adapters),将 `sapper build` 转换为 `vite build` ``
* `` 使用静态[适配器](adapters)将`将 sapper 导出`转换为`使用 vite 构建` ``
* `سپارک توسعه`应变为`ویت توسعه`
* `node __sapper__/build` 应变为 `node build`
##
项目文件
您的应用程序的大部分代码,在`src/routes`中可以保持不变,但几个项目文件需要移动或更新。
###
配置
您的`webpack.config.js`或`rollup.config.js`应替换为`svelte.config.js`,如文档[此处](configuration)所述。Svelte 预处理器选项应移动到`config.preprocess`。
您需要添加一个[适配器](adapters)。 `sapper build` 大约等同于 [adapter-node](adapter-node),而 `sapper export` 大约等同于 [adapter-static](adapter-static),尽管您可能更喜欢使用针对您部署的平台设计的适配器。
如果您正在使用由[Vite](https://vitejs.dev)自动处理的文件类型之外的插件,您将需要找到 Vite 的等效插件并将它们添加到[Vite 配置](project-structure#Project-files-vite.config.js)中。
### src/client.js
此文件在 SvelteKit 中没有等效项。任何超出`sapper.start(...)`的自定义逻辑都应该表达在你的`+layout.svelte`文件中,在`onMount`回调函数内。
### src/server.js
当使用`适配器节点`时,等效的是[自定义服务器](adapter-node#Custom-server)。否则,此文件没有直接等效项,因为 SvelteKit 应用可以在无服务器环境中运行。
### src/service-worker.js
大多数从`@sapper/service-worker`导入的内容在`$service-worker`中有等效项:
* `文件`保持不变
* `路由`已被删除
* `shell` 现在是 `build`
* `时间戳`现在是`版本`
### src/template.html
文件 `src/template.html` 应更名为 `src/app.html`。
删除 `%sapper.base%`,`%sapper.scripts%` 和 `%sapper.styles%`。将 `%sapper.head%` 替换为 `%sveltekit.head%`,并将 `%sapper.html%` 替换为 `%sveltekit.body%`。`
` 已不再必要。
###
src/节点模块
一个常见的模式是在 Sapper 应用中将您的内部库放在 `src/node_modules` 目录内。这在 Vite 中不适用,所以我们使用 [`src/lib`]($lib) 代替。
##
页面和布局
###
重命名文件
路由现在完全由文件夹名称组成,以消除歧义,直到`+page.svelte`的文件夹名称对应于路由。请参阅[路由文档](routing)以获取概述。以下显示的是新旧比较:
| 旧 | 新 |
| --- | --- |
| routes/about/index.svelte | routes/about/+page.svelte |
| routes/关于.svelte | routes/about/+page.svelte |
您的自定义错误页面组件应从`_error.svelte`重命名为`+error.svelte`。任何`_layout.svelte`文件也应相应重命名为`+layout.svelte`。[其他文件将被忽略](routing#Other-files)。
###
导入
The `goto`、`prefetch` 和 `prefetchRoutes` 从 `@sapper/app` 的导入应分别替换为从 [`$app/navigation`]($app-navigation) 的 `goto`、`preloadData` 和 `preloadCode` 导入。
The `stores` import from `@sapper/app` should be replaced — see the [Stores](migrating#Pages-and-layouts-Stores) section below.
任何您之前从`src/node_modules`目录中导入的文件都需要替换为`$lib`导入。
###
预加载
与之前一样,页面和布局可以导出一个功能,允许在渲染之前加载数据。
此函数已从 `preload` 重命名为 [`load`](load),现在位于其 `+page.js`(或 `+layout.js`)旁边,紧挨着其 `+page.svelte`(或 `+layout.svelte`),并且其 API 已更改。不再是两个参数——`page` 和 `session`——而是一个 `event` 参数。
没有更多 `此` 对象,因此也没有 `this.fetch`、`this.error` 或 `this.redirect`。相反,您可以从输入方法中获取 [`fetch`](load#Making-fetch-requests),而 [`error`](load#Errors) 和 [`redirect`](load#Redirects) 现在都会抛出。
###
商店
在 Sapper 中,你会这样获取提供的 store 引用:
```js
// @filename: ambient.d.ts
declare module '@sapper/app';
// @filename: index.js
// ---cut---
import { stores } from '@sapper/app';
const { preloading, page, session } = stores();
```
页面存储仍然存在;`预加载`已被替换为包含`from`和`to`属性的`导航`存储。`页面`现在有`url`和`params`属性,但没有`path`或`query`。
您在 SvelteKit 中访问它们的方式不同。\``stores`\`现在变为\``getStores`\`,但在大多数情况下这是不必要的,因为您可以直接从\`[`$app/stores`]($app-stores)\`导入\``navigating`\`和\``page`\`。如果您使用的是 Svelte 5 和 SvelteKit 2.12 或更高版本,请考虑使用\`[`$app/state`]($app-state)\`代替。
###
路由
正则表达式路由不再受支持。相反,请使用[高级路由匹配](advanced-routing#Matching)。
###
段
之前,布局组件接收一个 `segment` 属性来指示子段。这已被移除;您应使用更灵活的 `$page.url.pathname`(或 `page.url.pathname`)值来获取您感兴趣的段。
### URLs
在 Sapper 中,所有相对 URL 都是相对于基础 URL 解析的——通常是`/`,除非使用了`basepath`选项——而不是相对于当前页面。
这导致了问题,并且在 SvelteKit 中不再是这样。相反,相对 URL 是相对于当前页面(或目标页面,对于在`fetch` URL 中的`load`函数)解析的。在大多数情况下,使用根相对 URL(即以`/`开头)更容易,因为它们的含义不依赖于上下文。
###
属性
* `سپارک:prefetch` 现在是 `data-sveltekit-preload-data`
* `سپارک:noscroll` 现在是 `data-sveltekit-noscroll`
##
端点
在 Sapper 中,[服务器路由](routing#server)接收了 Node 的`http`模块(或 Polka 和 Express 等框架提供的增强版本)暴露的`req`和`res`对象。
SvelteKit 设计为对应用程序运行的位置无感知——它可以在 Node 服务器上运行,但同样也可以在无服务器平台或 Cloudflare Worker 上运行。因此,您不再直接与`req`和`res`交互。您的端点需要更新以匹配新的签名。
为了支持这种环境无关的行为,现在全局上下文中可用 `fetch`,因此您无需导入 `node-fetch`、`cross-fetch` 或类似的服务器端 fetch 实现,即可使用它。
##
集成
查看[集成](./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, // some hydration code needs comments, so leave them in
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;
}
}
});
}
```
请注意,当使用 `vit 预览` 测试网站的生成构建时,`预渲染` 为 `false`,因此要验证压缩结果,您需要直接检查构建的 HTML 文件。