高级
仅服务器模块
在 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
tsexport constVariable 'atlantisCoordinates' implicitly has an 'any[]' type.7005Variable 'atlantisCoordinates' implicitly has an 'any[]' type.= [/* redacted */]; atlantisCoordinates
$lib/server/secrets.ts
tsexport constatlantisCoordinates = [/* redacted */];
src/routes/utils.js
tsexport {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
tsexport {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'所决定。
延伸阅读永久链接
上一个 Service workers
下一个 Snapshots