跳至主要內容

僅限伺服器模組

就像一個好朋友一樣,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
export const const atlantisCoordinates: never[]atlantisCoordinates = [/* redacted */];
src/routes/utils
export { export atlantisCoordinatesatlantisCoordinates } from '$lib/server/secrets.js';

export const const add: (a: any, b: any) => anyadd = (a, b) => a: anya + b: anyb;

src/routes/+page
<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' 確定),會停用非法匯入檢測。

延伸閱讀

在 GitHub 上編輯此頁面

上一個 下一個