SvelteKit中如何按运行环境导入对应环境变量?
问题背景
我的问题与某StackOverflow问题类似,但希望使用SvelteKit动态变量而非Vite。我有一个API客户端ApiClient.ts,需要同时在客户端和服务端使用以实现服务端渲染。SvelteKit与API运行在同一个Kubernetes集群中,因此服务端希望直接调用http://api:8080,客户端调用https://my-url.com。我已将INTERNAL_API_URL存储在私有环境变量中,PUBLIC_API_URL存储在公共环境变量中。
疑问
能否根据运行环境(客户端时导入公共环境变量,服务端时导入私有环境变量)进行条件导入?示例代码如下:
// ApiClient.ts if (typeof window !== 'undefined') { import { env as publicEnv } from '$env/dynamic/public' } else { import { env as privateEnv } from '$env/dynamic/private' } // ...
解答
你不能像示例那样在条件分支里写静态import语句——静态导入是编译时处理的,无法放在运行时的条件判断中。不过有更简单的方案实现需求:
方案1:同时导入两个环境变量,条件取值
SvelteKit的动态环境变量在客户端运行时会自动忽略私有变量(不会暴露给前端),所以可以安全同时导入两个环境模块,再根据环境判断使用哪个URL:
// ApiClient.ts import { env as publicEnv } from '$env/dynamic/public'; import { env as privateEnv } from '$env/dynamic/private'; // 判断当前运行环境 const apiUrl = typeof window !== 'undefined' ? publicEnv.PUBLIC_API_URL : privateEnv.INTERNAL_API_URL; // 初始化你的API客户端 export const apiClient = new ApiClient(apiUrl);
方案2:使用SvelteKit内置的browser变量(更优雅)
SvelteKit在$app/environment中提供了browser变量,专门用来判断是否在客户端环境,比typeof window更直观:
// ApiClient.ts import { browser } from '$app/environment'; import { env as publicEnv } from '$env/dynamic/public'; import { env as privateEnv } from '$env/dynamic/private'; const apiUrl = browser ? publicEnv.PUBLIC_API_URL : privateEnv.INTERNAL_API_URL; export const apiClient = new ApiClient(apiUrl);
这两种方案都能实现服务端用私有内部API地址、客户端用公共外部地址的需求,同时保证私有环境变量不会泄露到前端。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

