仅服务端模块
SvelteKit 会像一个好朋友一样,保守您的秘密。在同一个代码仓库中编写后端和前端代码时,很容易不小心将敏感数据(例如包含 API 密钥的环境变量)导入到前端代码中。SvelteKit 提供了一种完全防止这种情况发生的方法:仅服务端模块(server-only modules)。
私有环境变量
$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 const atlantisCoordinates: never[]
atlantisCoordinates = [
/* 已编辑 */
];
src/routes/utils
export { export atlantisCoordinates
atlantisCoordinates } from '$lib/server/secrets.js';
export const const add: (a: any, b: any) => any
add = (a, b) => a: any
a + b: any
b;
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'
决定。
进一步阅读
上一页 下一页