高级
仅服务器模块
在 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'
所决定。
延伸阅读永久链接
上一个 Service workers
下一个 Snapshots