Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/config/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ async function _loadUserConfig(
let preset: string | undefined = (configOverrides.preset as string) || process.env.NITRO_PRESET || process.env.SERVER_PRESET

const _dotenv = opts.dotenv ?? (configOverrides.dev && { fileName: [".env", ".env.local"] });
const envName = opts.c12?.envName ?? (configOverrides.dev ? "development" : "production");
const loadedConfig = await (
opts.watch
? watchConfig<NitroConfig & { _meta?: NitroPresetMeta }>
Expand All @@ -87,6 +88,7 @@ async function _loadUserConfig(
name: "nitro",
cwd: configOverrides.rootDir,
dotenv: _dotenv,
envName,
extend: { extendKey: ["extends", "preset"] },
defaults: NitroDefaults,
async overrides({ rawConfigs }) {
Expand Down
74 changes: 74 additions & 0 deletions test/unit/config-loader-env.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "pathe";
import { afterEach, describe, expect, it, vi } from "vitest";

vi.mock("nitro/meta", () => ({
version: "0.0.0-test",
runtimeDir: "/tmp",
presetsDir: "/tmp",
pkgDir: "/tmp",
runtimeDependencies: [],
}));

const originalNodeEnv = process.env.NODE_ENV;
const tempDirs: string[] = [];

async function createFixtureConfig() {
const rootDir = await mkdtemp(join(tmpdir(), "nitro-config-env-"));
tempDirs.push(rootDir);

await writeFile(
join(rootDir, "nitro.config.ts"),
`export default defineNitroConfig({
preset: 'node-server',
routeRules: {
'/base': { headers: { 'x-env': 'base' } }
},
$production: {
routeRules: {
'/prod': { headers: { 'x-env': 'production' } }
}
},
$development: {
routeRules: {
'/dev': { headers: { 'x-env': 'development' } }
}
}
})
`
);

return rootDir;
}

afterEach(async () => {
process.env.NODE_ENV = originalNodeEnv;
for (const dir of tempDirs.splice(0, tempDirs.length)) {
await rm(dir, { recursive: true, force: true });
}
});

describe("config loader env layers", () => {
it("applies $production when NODE_ENV is unset and dev=false", async () => {
delete process.env.NODE_ENV;
const rootDir = await createFixtureConfig();

const { loadOptions } = await import("../../src/config/loader.ts");
const options = await loadOptions({ rootDir, dev: false });

expect(options.routeRules["/prod"]?.headers?.["x-env"]).toBe("production");
expect(options.routeRules["/dev"]).toBeUndefined();
});

it("applies $development when NODE_ENV is unset and dev=true", async () => {
delete process.env.NODE_ENV;
const rootDir = await createFixtureConfig();

const { loadOptions } = await import("../../src/config/loader.ts");
const options = await loadOptions({ rootDir, dev: true });

expect(options.routeRules["/dev"]?.headers?.["x-env"]).toBe("development");
expect(options.routeRules["/prod"]).toBeUndefined();
});
});