前言
Svelte,一個語法簡潔、入門容易,面向未來的前端框架。
從 Svelte 誕生之初,就備受開發者的喜愛,根據統計,從 2019 年到 2024 年,連續 6 年一直是開發者最感興趣的前端框架 No.1:
Svelte 以其獨特的編譯時優化機制著稱,具有輕量級、高性能、易上手等特性,非常適合構建輕量級 Web 項目。
為了幫助大家學習 Svelte,我同時搭建了 Svelte 最新的中文文檔站點。
如果需要進階學習,也可以入手我的小冊《Svelte 開發指南》,語法篇、實戰篇、原理篇三大篇章帶你系統掌握 Svelte!
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社群”,踏上“前端大佬成長之路”。
Netlify
要部署到 Netlify,請使用 adapter-netlify
。
當您使用 adapter-auto
時,此適配器將默認安裝,但將其添加到您的項目中可以指定 Netlify 特定的選項。
用法
使用 npm i -D @sveltejs/adapter-netlify
安裝,然后將適配器添加到您的 svelte.config.js
:
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-netlify';export default {kit: {// 顯示默認選項adapter: adapter({// 如果為 true,將創建 Netlify Edge Function 而不是// 使用標準的基于 Node 的函數edge: false,// 如果為 true,將把您的應用拆分為多個函數// 而不是為整個應用創建單個函數。// 如果 `edge` 為 true,則不能使用此選項split: false})}
};
然后,確保在項目根目錄中有一個 netlify.toml 文件。這將根據 build.publish
設置確定寫入靜態資源的位置,如此示例配置所示:
[build]command = "npm run build"publish = "build"
如果缺少 netlify.toml
文件或 build.publish
值,將使用默認值 "build"
。請注意,如果您在 Netlify UI 中將發布目錄設置為其他值,那么您也需要在 netlify.toml
中設置它,或使用默認值 "build"
。
Node 版本
新項目默認將使用當前的 Node LTS 版本。但是,如果您正在升級很久以前創建的項目,它可能會停留在舊版本上。有關手動指定當前 Node 版本的詳細信息,請參閱 Netlify 文檔。
Netlify Edge Functions
SvelteKit 支持 Netlify Edge Functions。如果您向 adapter
函數傳遞 edge: true
選項,服務端渲染將在部署在靠近站點訪問者的基于 Deno 的邊緣函數中進行。如果設置為 false
(默認值),站點將部署到基于 Node 的 Netlify Functions。
// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-netlify';export default {kit: {adapter: adapter({// 將使用基于 Deno 的 Netlify Edge Function// 而不是使用標準的基于 Node 的函數edge: true})}
};
SvelteKit 功能的 Netlify 替代方案
您可以直接使用 SvelteKit 提供的功能構建應用,而無需依賴任何 Netlify 功能。使用這些功能的 SvelteKit 版本將允許它們在開發模式下使用,通過集成測試進行測試,并在您決定切換到其他適配器時能夠正常工作。但是,在某些情況下,使用這些功能的 Netlify 版本可能會更有利。例如,如果您正在將已經托管在 Netlify 上的應用遷移到 SvelteKit。
重定向規則
在編譯期間,重定向規則會自動附加到您的 _redirects
文件中。(如果該文件尚不存在,它將被創建。)這意味著:
netlify.toml
中的[[redirects]]
永遠不會匹配,因為_redirects
具有更高的優先級。因此,始終將您的規則放在_redirects
文件中。_redirects
不應該有任何自定義的"捕獲所有"規則,如/* /foobar/:splat
。否則,由于 Netlify 只處理第一個匹配的規則,自動附加的規則將永遠不會被應用。
Netlify Forms
- 按照這里的描述創建您的 Netlify HTML 表單,例如作為
/routes/contact/+page.svelte
。(別忘了添加隱藏的form-name
input 元素!) - Netlify 的構建機器人在部署時解析您的 HTML 文件,這意味著您的表單必須預渲染為 HTML 。您可以在您的
contact.svelte
中添加export const prerender = true
來僅預渲染該頁面,或設置kit.prerender.force: true
選項來預渲染所有頁面。 - 如果您的 Netlify 表單有一個自定義成功消息,如
<form netlify ... action="/success">
,則確保相應的/routes/success/+page.svelte
存在并已預渲染。
Netlify Functions
使用此適配器,SvelteKit 端點將作為 Netlify Functions 托管。Netlify 函數處理程序具有額外的上下文,包括 Netlify Identity 信息。您可以通過您的 hooks 和 +page.server
或 +layout.server
端點中的 event.platform.context
字段訪問此上下文。當適配器配置中的 edge
屬性為 false
時,這些是serverless functions,當為 true
時,這些是edge functions。
// @errors: 2705 7006
/// file: +page.server.js
export const load = async (event) => {const context = event.platform.context;console.log(context); // 在 Netlify 應用的函數日志中顯示
};
此外,您可以通過創建一個目錄并在 netlify.toml
文件中添加配置來添加您自己的 Netlify 函數。例如:
[build]command = "npm run build"publish = "build"[functions]directory = "functions"
故障排除
訪問文件系統
您不能在 edge 部署中使用 fs
。
您可以在 serverless 部署中使用它,但它不會按預期工作,因為文件不會從您的項目復制到部署中。相反,使用 $app/server
中的 read
函數來訪問您的文件。read
在 edge 部署中不起作用(這在將來可能會改變)。
或者,您可以預渲染相關路由。
Vercel
要部署到 Vercel,請使用 adapter-vercel
。
當您使用 adapter-auto
時,這個適配器會被默認安裝,但將其添加到您的項目中可以讓您指定 Vercel 特定的選項。
用法
使用 npm i -D @sveltejs/adapter-vercel
安裝,然后將適配器添加到您的 svelte.config.js
中:
// @errors: 2307 2345
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-vercel';export default {kit: {adapter: adapter({// 可以在此處設置選項,詳見下文})}
};
部署配置
要控制您的路由如何作為函數部署到 Vercel,您可以通過上面顯示的選項或在 +server.js
、+page(.server).js
和 +layout(.server).js
文件中使用 export const config
來指定部署配置。
例如,您可以將應用的某些部分部署為 Edge Functions…
/// file: about/+page.js
/** @type {import('@sveltejs/adapter-vercel').Config} */
export const config = {runtime: 'edge'
};
…其他部分則作為 Serverless Functions(注意,在布局中指定 config
時,它會應用于所有子頁面):
/// file: admin/+layout.js
/** @type {import('@sveltejs/adapter-vercel').Config} */
export const config = {runtime: 'nodejs22.x'
};
以下選項適用于所有函數:
runtime
:'edge'
、'nodejs18.x'
、'nodejs20.x'
或'nodejs22.x'
。默認情況下,適配器會選擇與您的項目在 Vercel 儀表板上配置的 Node 版本對應的'nodejs<version>.x'
regions
:邊緣網絡區域數組(對于 serverless 函數默認為["iad1"]
)或當runtime
為edge
時為'all'
(其默認值)。注意,serverless 函數的多區域部署僅在企業版計劃中支持split
:如果為true
,會導致路由被部署為獨立函數。如果在適配器級別將split
設置為true
,所有路由都將被部署為獨立函數
此外,以下選項適用于 edge functions:
external
:esbuild 在打包函數時應該視為外部的依賴項數組。這只應用于排除在 Node 之外不會運行的可選依賴項
以下選項適用于 serverless 函數:
memory
:函數可用的內存量。默認為1024
Mb,可以降低到128
Mb 或在專業版或企業版賬戶中以 64Mb 為增量增加到3008
MbmaxDuration
:函數的最大執行時長。Hobby 賬戶默認為10
秒,Pro 為15
秒,Enterprise 為900
秒isr
:配置增量靜態重生成,詳見下文
如果您的函數需要訪問特定區域的數據,建議將它們部署在同一區域(或靠近該區域)以獲得最佳性能。
圖像優化
您可以設置 images
配置來控制 Vercel 如何構建您的圖像。完整細節請參見圖像配置參考。例如,您可以設置:
// @errors: 2300 2842 7031 1181 1005 1136 1128
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-vercel';export default {kit: {adapter({images: {sizes: [640, 828, 1200, 1920, 3840],formats: ['image/avif', 'image/webp'],minimumCacheTTL: 300,domains: ['example-app.vercel.app'],}})}
};
增量靜態重生成
Vercel 支持增量靜態重生成 (ISR),它提供了預渲染內容的性能和成本優勢,同時保持動態渲染內容的靈活性。
要為路由添加 ISR,在您的 config
對象中包含 isr
屬性:
// @errors: 2664
import { BYPASS_TOKEN } from '$env/static/private';export const config = {isr: {// 緩存資源將通過調用 Serverless 函數重新生成的過期時間(以秒為單位)。// 將值設置為 `false` 表示永不過期。expiration: 60,// 可以在 URL 中提供的隨機令牌,通過使用 __prerender_bypass=<token> cookie 請求資源來繞過緩存版本。//// 使用 `x-prerender-revalidate: <token>` 進行 `GET` 或 `HEAD` 請求將強制重新驗證資源。bypassToken: BYPASS_TOKEN,// 有效查詢參數列表。其他參數(如 utm 跟蹤代碼)將被忽略,// 確保它們不會導致不必要的內容重新生成allowQuery: ['search']}
};
expiration
屬性是必需的;其他都是可選的。
預渲染的頁面將忽略 ISR 配置。
環境變量
Vercel 提供了一組用于部署的特定的環境變量。像其他環境變量一樣,這些變量可以從 $env/static/private
和 $env/dynamic/private
訪問(有時候 — 稍后會詳細說明),并且不能從它們的公共對應項訪問。要從客戶端訪問這些變量之一:
// @errors: 2305
/// file: +layout.server.js
import { VERCEL_COMMIT_REF } from '$env/static/private';/** @type {import('./$types').LayoutServerLoad} */
export function load() {return {deploymentGitBranch: VERCEL_COMMIT_REF};
}
<!--- file: +layout.svelte --->
<script>/** @type {{ data: import('./$types').LayoutServerData }} */let { data } = $props();
</script><p>此暫存環境是從 {data.deploymentGitBranch} 部署的。</p>
由于在 Vercel 上構建時,所有這些變量在構建時和運行時之間都保持不變,我們建議使用 $env/static/private
(它會靜態替換變量,啟用死代碼消除等優化)而不是 $env/dynamic/private
。
版本偏差保護
當部署應用的新版本時,之前版本的資源可能不再可訪問。如果用戶在此時正在使用您的應用,在導航時可能會導致錯誤 — 這就是所謂的版本偏差。SvelteKit 通過檢測由版本偏差導致的錯誤并觸發硬重載來獲取應用的最新版本來緩解這個問題,但這會導致客戶端狀態丟失。(您也可以通過觀察 updated
store 值來主動緩解它,這個值會告訴客戶端何時部署了新版本。)
版本偏差保護是Vercel 的一個功能,可以將客戶端請求路由到它們的原始部署。當用戶訪問您的應用時,會設置一個帶有部署 ID 的 cookie,只要版本偏差保護處于活動狀態,任何后續請求都會被路由到該部署。當他們重新加載頁面時,將獲得最新的部署。(updated
store 不受此行為影響,因此將繼續報告新的部署。)要啟用它,請訪問 Vercel 上項目設置的高級部分。
基于 cookie 的版本偏差保護有一個注意事項:如果用戶在多個標簽頁中打開了您的應用的多個版本,舊版本的請求將被路由到較新的版本,這意味著它們將回退到 SvelteKit 的內置版本偏差保護。
注意事項
Vercel 函數
如果您在項目根目錄的 api
目錄中有 Vercel 函數,任何對 /api/*
的請求將不會由 SvelteKit 處理。您應該在您的 SvelteKit 應用中將這些實現為 API 路由,除非您需要使用非 JavaScript 語言,在這種情況下您需要確保您的 SvelteKit 應用中沒有任何 /api/*
路由。
Node 版本
在某個日期之前創建的項目可能默認使用比 SvelteKit 當前要求的更舊的 Node 版本。您可以在項目設置中更改 Node 版本。
故障排除
訪問文件系統
您不能在 edge functions 中使用 fs
。
您可以在 serverless 函數中使用它,但它不會按預期工作,因為文件不會從您的項目復制到您的部署中。相反,使用 $app/server
中的 read
函數來訪問您的文件。read
在部署為 edge functions 的路由中不起作用(這在將來可能會改變)。
或者,您可以預渲染相關路由。
Svelte 中文文檔
點擊查看中文文檔:
- SvelteKit Netlify
- SvelteKit Vercel
系統學習 Svelte,歡迎入手小冊《Svelte 開發指南》。語法篇、實戰篇、原理篇三大篇章帶你系統掌握 Svelte!
此外我還寫過 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答讀者問等 14 個系列文章, 全系列文章目錄:https://github.com/mqyqingfeng/Blog
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社群”,踏上“前端大佬成長之路”。