SvelteKit生产环境能否使用.env等运行时配置文件?
搞定SvelteKit构建后运行时改配置的方案
核心逻辑
要实现像.NET appsettings.json那样,build完随便改配置的效果,得分开处理服务端和客户端:
- 服务端直接读独立的配置文件就行,不用依赖构建时的注入
- 客户端得通过服务端给的接口拿配置,或者在页面入口塞全局变量,不能让配置被打包进静态文件里
服务端怎么弄
- 先在项目根目录建个
config.json,build之后把这个文件和build文件夹一起移走,改这个文件就生效:
{ "apiBaseUrl": "https://prod-api.example.com", "maxUploadSize": 10485760 }
- 在服务端代码里(比如
hooks.server.js或者API路由)动态读这个文件:
import fs from 'fs'; import path from 'path'; // 注意:build之后要保证config.json的路径是对的,根据部署环境调整就行 const configPath = path.join(process.cwd(), 'config.json'); export const serverConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
- 之后在服务端的路由或者hooks里直接用就行:
import { serverConfig } from '$lib/config/server'; export async function load() { return { apiUrl: serverConfig.apiBaseUrl }; }
客户端怎么弄
方法1:调用服务端接口拿配置
- 建个API路由
/api/config(路径是src/routes/api/config/+server.js):
import { serverConfig } from '$lib/config/server'; import { json } from '@sveltejs/kit'; export function GET() { // 只返回客户端能看的公开配置,别把敏感信息漏出去 const publicConfig = { apiBaseUrl: serverConfig.apiBaseUrl }; return json(publicConfig); }
- 在客户端的页面或者组件里请求这个接口:
let clientConfig; async function loadConfig() { const res = await fetch('/api/config'); clientConfig = await res.json(); } onMount(loadConfig);
方法2:在页面入口塞全局变量
- 改
src/routes/+layout.server.js,把配置传到页面上下文:
import { serverConfig } from '$lib/config/server'; export async function load() { return { publicConfig: { apiBaseUrl: serverConfig.apiBaseUrl } }; }
- 在根布局
src/routes/+layout.svelte里,把配置塞进全局window对象:
<script> export let data; </script> <svelte:head> <script> window.__APP_CONFIG__ = { apiBaseUrl: "{data.publicConfig.apiBaseUrl}" }; </script> </svelte:head> <slot />
- 之后在客户端组件里直接用这个全局变量就行:
const clientConfig = window.__APP_CONFIG__; console.log(clientConfig.apiBaseUrl);
为啥你之前用$env/dynamic-public没用
$env/dynamic-public是构建阶段把环境变量打进客户端代码里的,build完成后再改.env根本没用——因为这些值已经被打包进静态文件了,完全不适合你要的“build后修改配置”的场景。
内容的提问来源于stack exchange,提问作者Patryk
相关产品推荐
相关产品推荐

