仅在服务器端使用的模块

仅在服务器端使用的模块

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。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容