Skip to main content

Migrating from Sapper

SvelteKit 是 Sapper 的继任者,并共享其设计中的许多元素。

如果您已经有一个计划迁移到 SvelteKit 的 Sapper 应用程序,您将需要做出一些更改。在迁移过程中查看一些示例可能会有所帮助。一些示例

package.json

类型: “模块”

添加 "类型": "模块" 到您的 package.json。如果您使用的是 Sapper 0.29.3 或更高版本,您可以单独执行此步骤,作为增量迁移的一部分。

依赖关系

删除 polkaexpress,如果您使用其中之一,以及任何中间件,如 sirvcompression

开发依赖项

删除您的 devDependencies 中的 sapper,并用 @sveltejs/kit 和您计划使用的任何 适配器(见 下一节)替换。

脚本

任何引用 sapper 的脚本都需要更新:

  • 使用 Node [适配器](adapters),将 `sapper build` 转换为 `vite build`
  • 使用静态[适配器](adapters)将`将 sapper 导出`转换为`使用 vite 构建`
  • سپارک توسعه应变为ویت توسعه
  • node __sapper__/build 应变为 node build

项目文件

您的应用程序的大部分代码,在src/routes中可以保持不变,但几个项目文件需要移动或更新。

配置

您的webpack.config.jsrollup.config.js应替换为svelte.config.js,如文档此处所述。Svelte 预处理器选项应移动到config.preprocess

您需要添加一个适配器sapper build 大约等同于 adapter-node,而 sapper export 大约等同于 adapter-static,尽管您可能更喜欢使用针对您部署的平台设计的适配器。

如果您正在使用由Vite自动处理的文件类型之外的插件,您将需要找到 Vite 的等效插件并将它们添加到Vite 配置中。

src/client.js

此文件在 SvelteKit 中没有等效项。任何超出sapper.start(...)的自定义逻辑都应该表达在你的+layout.svelte文件中,在onMount回调函数内。

src/server.js

当使用适配器节点时,等效的是自定义服务器。否则,此文件没有直接等效项,因为 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%<div id="sapper"> 已不再必要。

src/节点模块

一个常见的模式是在 Sapper 应用中将您的内部库放在 src/node_modules 目录内。这在 Vite 中不适用,所以我们使用 src/lib 代替。

页面和布局

重命名文件

路由现在完全由文件夹名称组成,以消除歧义,直到+page.svelte的文件夹名称对应于路由。请参阅路由文档以获取概述。以下显示的是新旧比较:

routes/about/index.svelte routes/about/+page.svelte
routes/关于.svelte routes/about/+page.svelte

您的自定义错误页面组件应从_error.svelte重命名为+error.svelte。任何_layout.svelte文件也应相应重命名为+layout.svelte其他文件将被忽略

导入

The gotoprefetchprefetchRoutes@sapper/app 的导入应分别替换为从 $app/navigationgotopreloadDatapreloadCode 导入。

The stores import from @sapper/app should be replaced — see the Stores section below.

任何您之前从src/node_modules目录中导入的文件都需要替换为$lib导入。

预加载

与之前一样,页面和布局可以导出一个功能,允许在渲染之前加载数据。

此函数已从 preload 重命名为 load,现在位于其 +page.js(或 +layout.js)旁边,紧挨着其 +page.svelte(或 +layout.svelte),并且其 API 已更改。不再是两个参数——pagesession——而是一个 event 参数。

没有更多 对象,因此也没有 this.fetchthis.errorthis.redirect。相反,您可以从输入方法中获取 fetch,而 errorredirect 现在都会抛出。

商店

在 Sapper 中,你会这样获取提供的 store 引用:

import { module "@sapper/app"stores } from '@sapper/app';
const { const preloading: anypreloading, const page: anypage, const session: anysession } = module "@sapper/app"stores();

页面存储仍然存在;预加载已被替换为包含fromto属性的导航存储。页面现在有urlparams属性,但没有pathquery

您在 SvelteKit 中访问它们的方式不同。`stores`现在变为`getStores`,但在大多数情况下这是不必要的,因为您可以直接从`$app/stores`导入`navigating`和`page`。如果您使用的是 Svelte 5 和 SvelteKit 2.12 或更高版本,请考虑使用`$app/state`代替。

路由

正则表达式路由不再受支持。相反,请使用高级路由匹配

之前,布局组件接收一个 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 中,服务器路由接收了 Node 的http模块(或 Polka 和 Express 等框架提供的增强版本)暴露的reqres对象。

SvelteKit 设计为对应用程序运行的位置无感知——它可以在 Node 服务器上运行,但同样也可以在无服务器平台或 Cloudflare Worker 上运行。因此,您不再直接与reqres交互。您的端点需要更新以匹配新的签名。

为了支持这种环境无关的行为,现在全局上下文中可用 fetch,因此您无需导入 node-fetchcross-fetch 或类似的服务器端 fetch 实现,即可使用它。

集成

查看集成以获取有关集成的详细信息。

HTML 压缩器

Sapper 默认包含 html-minifier。SvelteKit 不包含此功能,但您可以将它作为生产依赖项添加,然后通过一个 钩子 使用它:

import { module "html-minifier"minify } from 'html-minifier';
import { const building: boolean

SvelteKit analyses your app during the build step by running it. During this process, building is true. This also applies during prerendering.

building
} from '$app/environment';
const
const minification_options: {
    collapseBooleanAttributes: boolean;
    collapseWhitespace: boolean;
    conservativeCollapse: boolean;
    decodeEntities: boolean;
    html5: boolean;
    ignoreCustomComments: RegExp[];
    minifyCSS: boolean;
    ... 8 more ...;
    sortClassName: boolean;
}
minification_options
= {
collapseBooleanAttributes: booleancollapseBooleanAttributes: true, collapseWhitespace: booleancollapseWhitespace: true, conservativeCollapse: booleanconservativeCollapse: true, decodeEntities: booleandecodeEntities: true, html5: booleanhtml5: true, ignoreCustomComments: RegExp[]ignoreCustomComments: [/^#/], minifyCSS: booleanminifyCSS: true, minifyJS: booleanminifyJS: false, removeAttributeQuotes: booleanremoveAttributeQuotes: true, removeComments: booleanremoveComments: false, // some hydration code needs comments, so leave them in removeOptionalTags: booleanremoveOptionalTags: true, removeRedundantAttributes: booleanremoveRedundantAttributes: true, removeScriptTypeAttributes: booleanremoveScriptTypeAttributes: true, removeStyleLinkTypeAttributes: booleanremoveStyleLinkTypeAttributes: true, sortAttributes: booleansortAttributes: true, sortClassName: booleansortClassName: true }; /** @type {import('@sveltejs/kit').Handle} */ export async function
function handle(input: {
    event: RequestEvent;
    resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}): MaybePromise<...>
@type{import('@sveltejs/kit').Handle}
handle
({ event: RequestEvent<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) {
let let page: stringpage = ''; return resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event, {
ResolveOptions.transformPageChunk?: ((input: {
    html: string;
    done: boolean;
}) => MaybePromise<string | undefined>) | undefined

Applies custom transforms to HTML. If done is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML (they could include an element’s opening tag but not its closing tag, for example) but they will always be split at sensible boundaries such as %sveltekit.head% or layout/page components.

@paraminput the html chunk and the info if this is the last chunk
transformPageChunk
: ({ html: stringhtml, done: booleandone }) => {
let page: stringpage += html: stringhtml; if (done: booleandone) { return const building: boolean

SvelteKit analyses your app during the build step by running it. During this process, building is true. This also applies during prerendering.

building
? module "html-minifier"minify(let page: stringpage,
const minification_options: {
    collapseBooleanAttributes: boolean;
    collapseWhitespace: boolean;
    conservativeCollapse: boolean;
    decodeEntities: boolean;
    html5: boolean;
    ignoreCustomComments: RegExp[];
    minifyCSS: boolean;
    ... 8 more ...;
    sortClassName: boolean;
}
minification_options
) : let page: stringpage;
} } }); }

请注意,当使用 vit 预览 测试网站的生成构建时,预渲染false,因此要验证压缩结果,您需要直接检查构建的 HTML 文件。

Edit this page on GitHub llms.txt