Skip to main content

Server-only modules

像一位好朋友一样,SvelteKit 保护你的秘密。当你在同一个仓库中编写后端和前端时,很容易不小心将敏感数据导入到前端代码中(例如包含 API 密钥的环境变量)。SvelteKit 提供了一种完全防止这种情况的方法:仅服务器模块。

私有环境变量

The $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 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'确定。

进一步阅读

Edit this page on GitHub llms.txt