進階
僅伺服器模組
在 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 constVariable 'atlantisCoordinates' implicitly has an 'any[]' type.7005Variable 'atlantisCoordinates' implicitly has an 'any[]' type.= [/* redacted */]; atlantisCoordinates
$lib/server/secrets.ts
ts
export constatlantisCoordinates = [/* redacted */];
src/routes/utils.js
ts
export {Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.2307Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.atlantisCoordinates } from'$lib/server/secrets.js' ;export constParameter 'a' implicitly has an 'any' type.add = (, a ) => b a +b ;
Parameter 'b' implicitly has an 'any' type.7006
7006Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
src/routes/utils.ts
ts
export {Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.2307Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.atlantisCoordinates } from'$lib/server/secrets.js' ;export constParameter 'a' implicitly has an 'any' type.add = (, a ) => b a +b ;
Parameter 'b' implicitly has an 'any' type.7006
7006Parameter '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'
判斷,因此在執行測試時會停用非法匯入偵測。