跳至主要內容

進階

僅伺服器模組

在 GitHub 上編輯此頁面

SvelteKit 就像一位好朋友,會為你保守秘密。在同一個儲存庫中撰寫後端和前端時,很容易不小心將敏感資料匯入到你的前端程式碼中(例如包含 API 金鑰的環境變數)。SvelteKit 提供了一個方法可以完全防止這種情況:僅伺服器模組。

私人環境變數

$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

運作方式

任何時候,只要你具有匯入僅伺服器程式碼(無論是直接或間接)的公開程式碼...

$lib/server/secrets.js
ts
export const atlantisCoordinates = [/* redacted */];
Variable 'atlantisCoordinates' implicitly has an 'any[]' type.7005Variable 'atlantisCoordinates' implicitly has an 'any[]' type.
$lib/server/secrets.ts
ts
export const atlantisCoordinates = [
/* redacted */
];
src/routes/utils.js
ts
export { atlantisCoordinates } from '$lib/server/secrets.js';
Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.2307Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.
export const add = (a, b) => a + b;
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
7006
7006
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
src/routes/utils.ts
ts
export { atlantisCoordinates } from '$lib/server/secrets.js';
Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.2307Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.
export const add = (a, b) => a + b;
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
7006
7006
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
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`),只有一個小警告:在開發期間,如果面向公眾的程式碼和僅伺服器模組之間有兩個或更多動態匯入,則在第一次載入程式碼時不會偵測到非法匯入。

像 Vitest 這樣的單元測試框架不會區分僅伺服器和面向公眾的程式碼。基於 process.env.TEST === 'true' 判斷,因此在執行測試時會停用非法匯入偵測。

進一步閱讀

下一頁 快照