從 Sapper 遷移
SvelteKit 是 Sapper 的後繼者,並沿用其設計的許多元素。
如果您現有的 Sapper 應用程式計劃遷移到 SvelteKit,則需要進行一些變更。您可能會發現遷移時查看一些範例很有幫助。
package.json
type: “module”
將 "type": "module"
新增至您的 package.json
。如果您使用 Sapper 0.29.3 或更新版本,可以將此步驟與其餘步驟分開作為增量遷移的一部分。
dependencies
移除 polka
或 express
(如果您正在使用其中之一),以及任何中介軟體,例如 sirv
或 compression
。
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.js
或 rollup.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/app
的 goto
、prefetch
和 prefetchRoutes
匯入應分別替換為來自 $app/navigation
的 goto
、preloadData
和 preloadCode
匯入。
來自 @sapper/app
的 stores
匯入應替換 — 請參閱下方的Stores章節。
您先前從 src/node_modules
中目錄匯入的任何檔案都需要替換為 $lib
匯入。
Preload
與之前一樣,頁面和版面配置可以匯出一個函式,以便在呈現之前載入資料。
此函式已從 preload
重新命名為 load
,現在位於其 +page.svelte
(或 +layout.svelte
)旁邊的 +page.js
(或 +layout.js
)中,並且其 API 已變更。不再有兩個引數 — page
和 session
— 而是一個單一的 event
引數。
不再有 this
物件,因此也沒有 this.fetch
、this.error
或 this.redirect
。相反地,您可以從輸入方法中取得 fetch
,並且 error
和 redirect
現在都會拋出。
Stores
在 Sapper 中,您將像這樣取得對提供儲存區的參考
import { module "@sapper/app"
stores } from '@sapper/app';
const { const preloading: any
preloading, const page: any
page, const session: any
session } = module "@sapper/app"
stores();
page
儲存區仍然存在;preloading
已被包含 from
和 to
屬性的 navigating
儲存區取代。page
現在具有 url
和 params
屬性,但沒有 path
或 query
。
您在 SvelteKit 中以不同的方式存取它們。stores
現在是 getStores
,但在大多數情況下,這是不必要的,因為您可以直接從 $app/stores
匯入 navigating
和 page
。
路由
不再支援 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
模組公開的 req
和 res
物件(或由 Polka 和 Express 等架構提供的增強版本)。
SvelteKit 設計為與應用程式的執行位置無關 — 它可能在 Node 伺服器上執行,但也可能在無伺服器平台或 Cloudflare Worker 中執行。因此,您不再直接與 req
和 res
互動。您的端點需要更新以符合新的簽名。
為了支援這種與環境無關的行為,fetch
現在可在全域環境中使用,因此您不需要匯入 node-fetch
、cross-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: boolean
collapseBooleanAttributes: true,
collapseWhitespace: boolean
collapseWhitespace: true,
conservativeCollapse: boolean
conservativeCollapse: true,
decodeEntities: boolean
decodeEntities: true,
html5: boolean
html5: true,
ignoreCustomComments: RegExp[]
ignoreCustomComments: [/^#/],
minifyCSS: boolean
minifyCSS: true,
minifyJS: boolean
minifyJS: false,
removeAttributeQuotes: boolean
removeAttributeQuotes: true,
removeComments: boolean
removeComments: false, // some hydration code needs comments, so leave them in
removeOptionalTags: boolean
removeOptionalTags: true,
removeRedundantAttributes: boolean
removeRedundantAttributes: true,
removeScriptTypeAttributes: boolean
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: boolean
removeStyleLinkTypeAttributes: true,
sortAttributes: boolean
sortAttributes: true,
sortClassName: boolean
sortClassName: true
};
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle(input: {
event: RequestEvent;
resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}): MaybePromise<...>
handle({ event: RequestEvent<Partial<Record<string, string>>, string | null>
event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve }) {
let let page: string
page = '';
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.
transformPageChunk: ({ html: string
html, done: boolean
done }) => {
let page: string
page += html: string
html;
if (done: boolean
done) {
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: string
page, 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: string
page;
}
}
});
}
請注意,當使用 vite preview
測試網站的生產版本時,prerendering
為 false
,因此若要驗證最小化的結果,您需要直接檢查建置的 HTML 檔案。