@sohu-bpd/unplugin-app-config
v0.1.0
Published
Generate typed application config from environment variables through virtual:app-config.
Downloads
96
Readme
@sohu-bpd/unplugin-app-config
Generate typed application config from environment variables through virtual:app-config.
Features
- exposes
virtual:app-config - supports both named exports and a default export object
- filters environment variables before exposing them to app code
- supports global naming rules and per-variable schema overrides
- supports named grouped exports via
groups - coerces
string,number,boolean, andjsonvalues - generates a single TypeScript declaration file at
.sohu/app-config.d.ts
Host Support
The package root exports the shared unplugin factory object. In app config, prefer the host-specific subpaths:
@sohu-bpd/unplugin-app-config/vite@sohu-bpd/unplugin-app-config/rollup@sohu-bpd/unplugin-app-config/webpack@sohu-bpd/unplugin-app-config/rspack@sohu-bpd/unplugin-app-config/rolldown
Rsbuild should use the /rspack entry through tools.rspack; there is no separate ./rsbuild export.
Usage
Vite
import { defineConfig } from "vite";
import appConfigPlugin from "@sohu-bpd/unplugin-app-config/vite";
export default defineConfig({
plugins: [
appConfigPlugin({
include: ["VITE_APP_*"],
naming: {
stripPrefixes: ["VITE_APP_"],
case: "camelCase"
},
groups: {
cdn: ["VITE_APP_CDN_*"]
},
schema: {
VITE_APP_BASE_URL: {
type: "string",
required: true
},
VITE_APP_ENABLE_DEBUG: {
exportName: "debug",
type: "boolean",
default: false
},
VITE_APP_FLAGS: {
exportName: "flags",
type: "json",
default: {}
}
}
})
]
});Rollup
import appConfigPlugin from "@sohu-bpd/unplugin-app-config/rollup";
export default {
plugins: [
appConfigPlugin({
include: ["APP_*"],
naming: {
stripPrefixes: ["APP_"],
case: "camelCase"
},
schema: {
APP_API_BASE_URL: {
type: "string",
required: true
}
}
})
]
};Other Hosts
- Use
@sohu-bpd/unplugin-app-config/webpackin webpack configs. - Use
@sohu-bpd/unplugin-app-config/rspackin Rspack configs and in Rsbuild viatools.rspack.plugins. - Use
@sohu-bpd/unplugin-app-config/rolldownin Rolldown configs.
Virtual Module
The plugin exposes a single runtime module:
import appConfig, { baseUrl, debug, flags } from "virtual:app-config";Generated values are resolved at build time. The module exports:
- named exports for each resolved config item
- a frozen default export object containing the same entries
TypeScript types are provided through the generated declaration file .sohu/app-config.d.ts, not through a separate virtual:app-config.d.ts import path.
Options
include
Required glob rule or glob rule list describing which env keys are candidates for export.
exclude
Optional glob rule or glob rule list describing keys that should be filtered out after include.
env
Optional explicit env input:
{
mode?: string;
values?: Record<string, string | undefined>;
}Resolution order is:
- host-resolved env when available
- explicit
env.values process.env
naming
Global naming rules for schema-less keys and schema entries without exportName overrides:
{
stripPrefixes?: string | string[];
case?: "original" | "constantCase" | "camelCase" | "pascalCase";
}groups
Optional named scopes for matching env keys:
{
[groupName: string]: string | string[];
}Each group key becomes a nested export object in virtual:app-config. Grouped keys keep using the same global naming rules as flat keys, and once a key matches a group it no longer appears at the top level.
Example:
groups: {
cdn: ["VITE_APP_CDN_*"]
}With naming.stripPrefixes: ["VITE_APP_CDN_", "VITE_APP_"], VITE_APP_CDN_BASE_PATH becomes cdn.basePath.
schema
Per-variable overrides keyed by env variable name:
{
[envKey: string]: {
exportName?: string;
type: "string" | "number" | "boolean" | "json";
required?: boolean;
default?: unknown;
transform?: (value: unknown) => unknown;
validate?: (value: unknown) => boolean | string;
description?: string;
};
}When a schema entry exists, it controls type coercion, defaults, validation, and any explicit export name override. Keys without schema entries still resolve through the global naming rules and default to string output.
Behavior
virtual:app-configis generated from resolved entries at load time inside the plugin.- when a supported host runs the plugin and resolves the current app config output, the plugin writes
.sohu/app-config.d.ts - Missing required schema values fail the build.
- Duplicate export names fail the build.
- Grouped keys are omitted from the top level and only exported on their named scope.
- Validation failures throw either the default validator error or the custom string returned by
validate.
TypeScript
After the plugin runs once in any supported host, it generates:
.sohu/app-config.d.tsTo make TypeScript load those declarations, include .sohu/**/*.d.ts in your tsconfig.json:
{
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
".sohu/**/*.d.ts"
]
}virtual:app-config then resolves to a generated declaration similar to:
declare module "virtual:app-config" {
export const baseUrl: string;
export const debug: boolean;
const appConfig: {
baseUrl: string;
debug: boolean;
};
export default appConfig;
}