仅在服务器端使用的模块
SvelteKit像一位可靠的朋友,会替你保守秘密。把前后端写在同一个代码仓库时,很容易意外把敏感数据导入前端代码,例如包含API密钥的环境变量。SvelteKit通过“仅服务器端模块”防止这种情况发生。
私有环境变量
$app/env/private只能导入到仅在服务器运行的模块中,例如hooks.server.js或+page.server.js。
仅服务器端工具
$app/server包含从文件系统读取资源的read函数,同样只能由服务器端代码导入。
自己编写的模块
有两种方式将模块标记为仅在服务器端使用:
- 在文件名中加入
server段,例如server.js或secrets.server.ts。项目目录中的任意文件都适用。 - 将模块放入项目中的某个
server目录,但不能位于src/routes或static目录内。例如src/lib/server/config.js或src/lib/data/server/user/profile.js。
旧版本模式:在SvelteKit 2中,只识别src/lib下的server目录。
工作目录之外,以及node_modules中的模块,例如npm包,不受这些规则约束。如果要发布包含仅服务器端模块的软件包,请在该文件顶部加入import '$app/server'。
工作原理
只要面向浏览器的代码直接或间接导入仅服务器端代码,例如:
#lib/server/secrets.js
export const atlantisCoordinates = [/* redacted */];
src/routes/utils.js
export { atlantisCoordinates } from '#lib/server/secrets.js';
export const add = (a, b) => a + b;
src/routes/+page.svelte
<script>
import { add } from './utils.js';
</script>
SvelteKit就会报错:
Cannot import #lib/server/secrets.ts into code that runs in the browser, as this could leak sensitive information.
src/routes/+page.svelte imports
src/routes/utils.js imports
#lib/server/secrets.ts
If you're only using the import as a type, change it to `import type`.
虽然面向浏览器的src/routes/+page.svelte只使用导出的add,没有使用敏感的atlantisCoordinates,敏感代码仍可能进入浏览器下载的JavaScript,因此这条导入链被视为不安全。
这项检测也适用于动态导入,甚至包括await import(`./${foo}.js`)这样的插值导入。
注意:Vitest等单元测试框架不区分仅服务器端代码与面向浏览器的代码。因此,运行测试时会禁用非法导入检测;判断条件为process.env.TEST === 'true'。
延伸阅读
来源与版权
原文:Server-only modules,SvelteKit文档。中文译文。版权归Svelte项目及贡献者所有。本文采用原HTML页面所展示的API与旧版本说明。
仓库许可:MIT License。











暂无评论内容