跳至主要內容

從 Sapper 遷移

SvelteKit 是 Sapper 的後繼者,並沿用其設計的許多元素。

如果您現有的 Sapper 應用程式計劃遷移到 SvelteKit,則需要進行一些變更。您可能會發現遷移時查看一些範例很有幫助。

package.json

type: “module”

"type": "module" 新增至您的 package.json。如果您使用 Sapper 0.29.3 或更新版本,可以將此步驟與其餘步驟分開作為增量遷移的一部分。

dependencies

移除 polkaexpress(如果您正在使用其中之一),以及任何中介軟體,例如 sirvcompression

devDependencies

從您的 devDependencies 中移除 sapper,並將其替換為 @sveltejs/kit 以及您計劃使用的任何轉接器(請參閱下一節)。

scripts

應更新任何引用 sapper 的指令碼

  • sapper build 應使用 Node 轉接器變成 vite build
  • sapper export 應使用靜態轉接器變成 vite build
  • sapper dev 應變成 vite dev
  • 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

當使用 adapter-node 時,等效項目是自訂伺服器。否則,此檔案沒有直接對應的項目,因為 SvelteKit 應用程式可以在無伺服器環境中執行。

src/service-worker.js

來自 @sapper/service-worker 的大多數匯入在 $service-worker 中都有對等項目

  • files 未變更
  • routes 已移除
  • shell 現在為 build
  • timestamp 現在為 version

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/node_modules

Sapper 應用程式中的常見模式是將您的內部程式庫放在 src/node_modules 內的目錄中。這不適用於 Vite,因此我們改用 src/lib

頁面和版面配置

重新命名的檔案

路由現在完全由資料夾名稱組成,以消除歧義,導向 +page.svelte 的資料夾名稱對應於路由。請參閱路由文件以取得概觀。以下顯示新舊比較

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

您的自訂錯誤頁面元件應從 _error.svelte 重新命名為 +error.svelte。任何 _layout.svelte 檔案也應同樣重新命名為 +layout.svelte任何其他檔案都會被忽略

匯入

來自 @sapper/appgotoprefetchprefetchRoutes 匯入應分別替換為來自 $app/navigationgotopreloadDatapreloadCode 匯入。

來自 @sapper/appstores 匯入應替換 — 請參閱下方的Stores章節。

您先前從 src/node_modules 中目錄匯入的任何檔案都需要替換為 $lib 匯入。

Preload

與之前一樣,頁面和版面配置可以匯出一個函式,以便在呈現之前載入資料。

此函式已從 preload 重新命名為 load,現在位於其 +page.svelte(或 +layout.svelte)旁邊的 +page.js(或 +layout.js)中,並且其 API 已變更。不再有兩個引數 — pagesession — 而是一個單一的 event 引數。

不再有 this 物件,因此也沒有 this.fetchthis.errorthis.redirect。相反地,您可以從輸入方法中取得 fetch,並且 errorredirect 現在都會拋出。

Stores

在 Sapper 中,您將像這樣取得對提供儲存區的參考

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

page 儲存區仍然存在;preloading 已被包含 fromto 屬性的 navigating 儲存區取代。page 現在具有 urlparams 屬性,但沒有 pathquery

您在 SvelteKit 中以不同的方式存取它們。stores 現在是 getStores,但在大多數情況下,這是不必要的,因為您可以直接從 $app/stores 匯入 navigatingpage

路由

不再支援 Regex 路由。請改用進階路由比對

區段

先前,版面配置元件會接收一個 segment 屬性,指示子區段。此屬性已移除;您應該使用更靈活的 $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

端點

在 Sapper 中,伺服器路由會接收由 Node 的 http 模組公開的 reqres 物件(或由 Polka 和 Express 等架構提供的增強版本)。

SvelteKit 設計為與應用程式的執行位置無關 — 它可能在 Node 伺服器上執行,但也可能在無伺服器平台或 Cloudflare Worker 中執行。因此,您不再直接與 reqres 互動。您的端點需要更新以符合新的簽名。

為了支援這種與環境無關的行為,fetch 現在可在全域環境中使用,因此您不需要匯入 node-fetchcross-fetch 或類似的伺服器端 fetch 實作才能使用它。

整合

請參閱 整合 以取得有關整合的詳細資訊。

HTML 最小化器

Sapper 預設包含 html-minifier。SvelteKit 不包含此項目,但您可以將其新增為 prod 依賴項,然後透過鉤子使用它

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>

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;
} } }); }

請注意,當使用 vite preview 測試網站的生產版本時,prerenderingfalse,因此若要驗證最小化的結果,您需要直接檢查建置的 HTML 檔案。

在 GitHub 上編輯此頁面