像一位好朋友一样,SvelteKit 保护你的秘密。当你在同一个仓库中编写后端和前端时,很容易不小心将敏感数据导入到前端代码中(例如包含 API 密钥的环境变量)。SvelteKit 提供了一种完全防止这种情况的方法:仅服务器模块。 ## 私有环境变量 The [`$env/static/private`]($env-static-private) 和 [`$env/dynamic/private`]($env-dynamic-private) 模块只能导入到仅在服务器上运行的模块中,例如 [`hooks.server.js`](hooks#Server-hooks) 或 [`+page.server.js`](routing#page-page.server.js)。 ## 服务器专用工具 该 [`$app/server`]($app-server) 模块,其中包含一个用于从文件系统中读取资源的 [`read`]($app-server#read) 函数,同样只能由在服务器上运行的代码导入。 ## 您的模块 您可以通过两种方式将您的模块设置为仅服务器端: * 添加 `.server` 到文件名中,例如 `secrets.server.js` * 将它们放置在`$lib/server`中,例如`$lib/server/secrets.js` ## 如何工作 任何时间当你有面向公众的代码导入仅服务器端代码(无论是直接还是间接)... ```js // @errors: 7005 /// file: $lib/server/secrets.js export const atlantisCoordinates = [/* redacted */]; ``` ```js // @errors: 2307 7006 7005 /// file: src/routes/utils.js export { atlantisCoordinates } from '$lib/server/secrets.js'; export const add = (a, b) => a + b; ``` ```html /// file: src/routes/+page.svelte ``` ...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'`确定。 ## 进一步阅读 * [ 教程:环境变量](/tutorial/kit/env-static-private)