前言
Svelte,一個語法簡潔、入門容易,面向未來的前端框架。
從 Svelte 誕生之初,就備受開發者的喜愛,根據統計,從 2019 年到 2024 年,連續 6 年一直是開發者最感興趣的前端框架 No.1:
Svelte 以其獨特的編譯時優化機制著稱,具有輕量級、高性能、易上手等特性,非常適合構建輕量級 Web 項目。
為了幫助大家學習 Svelte,我同時搭建了 Svelte 最新的中文文檔站點。
如果需要進階學習,也可以入手我的小冊《Svelte 開發指南》,語法篇、實戰篇、原理篇三大篇章帶你係統掌握 Svelte!
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社羣”,踏上“前端大佬成長之路”。
僅服務端模塊
SvelteKit 會像一個好朋友一樣,保守您的秘密。在同一個代碼倉庫中編寫後端和前端代碼時,很容易不小心將敏感數據(例如包含 API 密鑰的環境變量)導入到前端代碼中。SvelteKit 提供了一種完全防止這種情況發生的方法:僅服務端模塊(server-only modules)。
私有環境變量
$env/static/private 和 $env/dynamic/private 模塊只能導入到僅在服務端上運行的模塊中,例如 hooks.server.js 或 +page.server.js。
僅服務端工具
$app/server 模塊包含一個 read 函數,用於從文件系統讀取資源,同樣只能被服務端運行的代碼導入。
您的模塊
您可以通過兩種方式使您的模塊成為僅服務端模塊:
- 在文件名中添加
.server,例如secrets.server.js - 將它們放在
$lib/server中,例如$lib/server/secrets.js
工作原理
任何時候,當您有公開的代碼,導入僅服務端代碼時(無論是直接還是間接)...
// @errors: 7005
/// file: $lib/server/secrets.js
export const atlantisCoordinates = [
/* 已編輯 */
];
// @errors: 2307 7006 7005
/// file: src/routes/utils.js
export { atlantisCoordinates } from '$lib/server/secrets.js';
export const add = (a, b) => a + b;
/// file: src/routes/+page.svelte
<script>
import { add } from './utils.js';
</script>
...SvelteKit 將報錯:
Cannot import $lib/server/secrets.js into public-facing code:
- src/routes/+page.svelte
- src/routes/utils.js
- $lib/server/secrets.js
儘管公開代碼 — src/routes/+page.svelte — 只使用了 add 導出而沒有使用秘密的 atlantisCoordinates 導出,秘密代碼也可能最終出現在瀏覽器下載的 JavaScript 中,因此這個導入鏈被認為是不安全的。
此功能也適用於動態導入,甚至是像 await import(`./${foo}.js`) 這樣的插值導入,只有一個小注意點:在開發過程中,如果公開代碼和僅服務端模塊之間存在兩個或更多的動態導入,則在第一次加載代碼時不會檢測到非法導入。
[!NOTE] 像 Vitest 這樣的單元測試框架不區分僅服務端代碼和公開代碼。因此,當運行測試時,非法導入檢測會被禁用,這由 process.env.TEST === 'true' 決定。
進一步閲讀
- 教程:環境變量
快照
臨時的 DOM 狀態 — 比如側邊欄的滾動位置、<input> 元素的內容等 — 在從一個頁面導航到另一個頁面時會被丟棄。
例如,如果用户填寫了一個表單但在提交之前離開並返回,或者用户刷新頁面,他們填寫的值將會丟失。在需要保留這些輸入的情況下,您可以創建一個 DOM 狀態的快照,當用户返回時可以恢復這個狀態。
要實現這一點,從 +page.svelte 或 +layout.svelte 中導出一個帶有 capture 和 restore 方法的 snapshot 對象:
<!--- file: +page.svelte --->
<script>
let comment = $state('');
/** @type {import('./$types').Snapshot<string>} */
export const snapshot = {
capture: () => comment,
restore: (value) => comment = value
};
</script>
<form method="POST">
<label for="comment">評論</label>
<textarea id="comment" bind:value={comment} />
<button>發表評論</button>
</form>
當您離開這個頁面時,capture 函數會在頁面更新之前立即被調用,返回的值會與瀏覽器歷史棧中的當前記錄關聯。如果您返回此頁面,restore 函數會在頁面更新後立即被調用,並傳入存儲的值。
數據必須是可以序列化為 JSON 的,這樣它才能被保存到 sessionStorage 中。這樣就可以在頁面重新加載時,或者用户從其他網站返回時恢復狀態。
[!NOTE] 避免從capture返回非常大的對象 — 一旦被捕獲,對象將在會話期間保留在內存中,在極端情況下可能會因太大而無法保存到sessionStorage中。
Svelte 中文文檔
點擊查看中文文檔:
- SvelteKit 僅服務端模塊
- SvelteKit 快照
系統學習 Svelte,歡迎入手小冊《Svelte 開發指南》。語法篇、實戰篇、原理篇三大篇章帶你係統掌握 Svelte!
此外我還寫過 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答讀者問等 14 個系列文章, 全系列文章目錄:https://github.com/mqyqingfeng/Blog
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社羣”,踏上“前端大佬成長之路”。