SvelteKit 环境变量

环境变量是应用需要、但独立于应用源代码存在的值。它让你能够使用 API 密钥、数据库凭据等敏感信息,而不必将它们保存在版本控制中。

开发期间及构建时,.env 或 .env.local 文件定义的变量会加入环境。例如 .env:

API_KEY=19f401ba-e8b0-48c4-8c77-b0ebb26d97fe

按照下面的方式完成配置后,可以通过以下模块导入这些变量:

  • $app/env/private
  • $app/env/public

旧模式:$env/* 模块和 $app/environment 已在 SvelteKit 3 中弃用,将在 SvelteKit 4 中移除。替代方案是显式环境变量,这项功能最初在 SvelteKit 2.62 中作为实验选项引入。

配置

添加 src/env.ts 或 src/env.js 文件,导出一个 variables 对象:

import { defineEnvVars } from '@sveltejs/kit/env';

export const variables = defineEnvVars({
	// ...
});

传入 defineEnvVars 的对象中,每个值都是一个用于配置环境变量的 EnvVarConfig 对象。

defineEnvVars 原样返回传入参数,它的作用仅仅是帮助保证类型安全。

私有变量

默认情况下,所有变量都视为私有变量。例如,你不会希望泄露 API_KEY:

import { defineEnvVars } from '@sveltejs/kit/env';

export const variables = defineEnvVars({
	API_KEY: {}
});

这个变量不需要额外配置,因此可以使用空对象 {}。

定义 API_KEY 后,即可通过 $app/env/private 将它导入应用代码:

import { API_KEY } from '$app/env/private';

$app/env/private 不能导入到在浏览器中运行的代码,因此不会因为 JavaScript 打包而意外泄露秘密。

公共变量

有些变量暴露给浏览器完全安全,甚至必须暴露。对这类变量,可以指定 public: true:

import { defineEnvVars } from '@sveltejs/kit/env';

export const variables = defineEnvVars({
	GOOGLE_ANALYTICS_ID: {
		public: true
	}
});

现在可以从 $app/env/public 导入 GOOGLE_ANALYTICS_ID,也可以在 app.html 模板中用 %sveltekit.env.GOOGLE_ANALYTICS_ID% 引用它:

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" href="%sveltekit.assets%/favicon.png" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		%sveltekit.head%

		<script
			async
			src="https://www.googletagmanager.com/gtag/js?id=%sveltekit.env.GOOGLE_ANALYTICS_ID%"
		></script>

		<script>
			window.dataLayer ??= [];
			function gtag(){dataLayer.push(arguments)}
			gtag('js', new Date());
			gtag('config', '%sveltekit.env.GOOGLE_ANALYTICS_ID%');
		</script>
	</head>
	<body data-sveltekit-preload-data="hover">
		<div style="display: contents">%sveltekit.body%</div>
	</body>
</html>

验证

可以指定符合 Standard Schema 标准的验证器,例如 Zod 或 Valibot,以检查环境变量的值是否正确:

import { defineEnvVars } from '@sveltejs/kit/env';
import * as v from 'valibot';

export const variables = defineEnvVars({
	GOOGLE_ANALYTICS_ID: {
		public: true,
		schema: v.pipe(v.string(), v.regex(/G-[A-Z0-9]+/))
	}
});

如果不想引入模式验证库,可以传入一个函数。函数返回经过处理或未处理的值;出现问题时,抛出说明原因的错误:

import { defineEnvVars } from '@sveltejs/kit/env';

export const variables = defineEnvVars({
	GOOGLE_ANALYTICS_ID: {
		public: true,
		schema: (value) => {
			if (!value?.startsWith('G-')) throw new Error('expected a Google Analytics ID');
			return value;
		}
	}
});

如果值无效,应用将无法启动或构建。如果希望仅在启动或构建其中一个阶段要求有效值,可以结合 $app/env 中的 building 与允许可选值的验证器:

import { defineEnvVars } from '@sveltejs/kit/env';
import { building } from '$app/env'
import * as v from 'valibot';

export const variables = defineEnvVars({
	SECRET: {
		// optional when building but required when starting the app
		schema: building ? v.optional(v.string()) : v.string()
	}
});

还可以使用验证器将值设为可选,或对其进行转换,例如将字符串转换为布尔值、解析 JSON。具体方法请查阅所用验证库的文档。

静态变量

变量默认为动态变量。如果将变量配置为 static: true,它会被内联到应用代码中,从而启用死代码消除等优化:

import { defineEnvVars } from '@sveltejs/kit/env';
import * as v from 'valibot';

export const variables = defineEnvVars({
	SHOW_DEBUG_OVERLAY: {
		public: true,
		static: true,

		// coerce to true/false
		schema: v.pipe(
			v.optional(v.string(), ''),
			v.transform((str) => str !== '')
		)
	}
});

因为这个变量是静态的,除非 SHOW_DEBUG_OVERLAY 为真值,否则下面的 <DebugOverlay> 组件不会包含在 JavaScript 包中:

<script>
	import { SHOW_DEBUG_OVERLAY } from '$app/env/public';
	import DebugOverlay from '#lib/components/DebugOverlay.svelte';
</script>

{#if SHOW_DEBUG_OVERLAY}
	<DebugOverlay />
{/if}

不过,如果在构建应用之前设置该变量:

SHOW_DEBUG_OVERLAY=true npm run build

这个组件就会包含在构建中并显示出来。

为变量编写说明

可以添加 description,说明环境变量的用途:

import { defineEnvVars } from '@sveltejs/kit/env';

export const variables = defineEnvVars({
	CACHE_TTL_SECONDS: {
		description: 'How long to cache responses, in seconds'
	}
});

在应用代码中,将鼠标悬停在 CACHE_TTL_SECONDS 上,就会显示这段说明。


原文:Environment variables。作者/维护方:SvelteKit 文档维护者。本文为中文翻译,代码及命令保留原文。

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

请登录后发表评论

    暂无评论内容