Skip to content

Commit 8c9ad3d

Browse files
committed
feat: add env:*
1 parent 926336c commit 8c9ad3d

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

packages/start/src/config/env.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { loadEnv, type Plugin } from "vite";
2+
3+
export interface EnvPluginOptions {
4+
server?: {
5+
load?: () => Record<string, string>;
6+
prefix?: string;
7+
};
8+
client?: {
9+
load?: () => Record<string, string>;
10+
prefix?: string;
11+
};
12+
}
13+
14+
const SERVER_ENV = "env:server";
15+
const CLIENT_ENV = "env:client";
16+
17+
const DEFAULT_SERVER_PREFIX = "SERVER_";
18+
const DEFAULT_CLIENT_PREFIX = "CLIENT_";
19+
20+
const SERVER_ONLY_MODULE = `throw new Error('Attempt to load server-only environment variables in client runtime.');`;
21+
22+
function convertObjectToModule(object: Record<string, string>): string {
23+
let result = "";
24+
for (const key in object) {
25+
result += `export const ${key} = ${JSON.stringify(object[key])};`;
26+
}
27+
return result;
28+
}
29+
30+
export function envPlugin(options?: EnvPluginOptions): Plugin {
31+
const currentOptions = options ?? {};
32+
let env: string;
33+
const serverPrefix = currentOptions.server?.prefix ?? DEFAULT_SERVER_PREFIX;
34+
const clientPrefix = currentOptions.client?.prefix ?? DEFAULT_CLIENT_PREFIX;
35+
return {
36+
name: "solid-start:env",
37+
enforce: "pre",
38+
configResolved(config) {
39+
env = config.mode !== "production" ? "development" : "production";
40+
},
41+
resolveId(id) {
42+
if (id === SERVER_ENV || id === CLIENT_ENV) {
43+
return id;
44+
}
45+
return null;
46+
},
47+
load(id, opts) {
48+
if (id === SERVER_ENV) {
49+
if (!opts?.ssr) {
50+
return SERVER_ONLY_MODULE;
51+
}
52+
const vars = currentOptions.server?.load
53+
? currentOptions.server.load()
54+
: loadEnv(env, false, clientPrefix);
55+
return convertObjectToModule(vars);
56+
}
57+
if (id === CLIENT_ENV) {
58+
const vars = currentOptions.client?.load
59+
? currentOptions.client.load()
60+
: loadEnv(env, false, serverPrefix);
61+
return convertObjectToModule(vars);
62+
}
63+
return null;
64+
},
65+
};
66+
}

packages/start/src/config/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import solid, { type Options as SolidOptions } from "vite-plugin-solid";
88

99
import { DEFAULT_EXTENSIONS, VIRTUAL_MODULES, VITE_ENVIRONMENTS } from "./constants.ts";
1010
import { devServer } from "./dev-server.ts";
11+
import { EnvPluginOptions, envPlugin } from "./env.ts";
1112
import { SolidStartClientFileRouter, SolidStartServerFileRouter } from "./fs-router.ts";
1213
import { fsRoutes } from "./fs-routes/index.ts";
1314
import type { BaseFileSystemRouter } from "./fs-routes/router.ts";
@@ -32,6 +33,7 @@ export interface SolidStartOptions {
3233
*/
3334
mode?: "js" | "json";
3435
};
36+
env?: EnvPluginOptions;
3537
}
3638

3739
const absolute = (path: string, root: string) =>
@@ -175,6 +177,7 @@ export function solidStart(options?: SolidStartOptions): Array<PluginOption> {
175177
},
176178
}),
177179
lazy(),
180+
envPlugin(options?.env),
178181
// Must be placed after fsRoutes, as treeShake will remove the
179182
// server fn exports added in by this plugin
180183
TanStackServerFnPlugin({

0 commit comments

Comments
 (0)