import { config } from 'dotenv'; import { existsSync } from 'fs'; import { resolve } from 'path'; /** * 环境变量加载策略(后加载的文件覆盖先前的同名键): * * - local:`.env` + `.env.local` * - staging:`.env.staging` + `.env.staging.local`(同机测试栈,APP_ENV=staging) * - production:`.env.production` + `.env.production.local` * * 判定:优先 `APP_ENV`;未设置时 `NODE_ENV=production` → production,否则 local。 * staging 在 PM2 中仍设 `NODE_ENV=production`(构建产物),靠 `APP_ENV=staging` 区分。 */ const apiRoot = resolve(__dirname, '..'); const nodeEnv = process.env.NODE_ENV ?? 'development'; function resolveAppEnv(): 'local' | 'staging' | 'production' { const raw = (process.env.APP_ENV ?? '').trim().toLowerCase(); if (raw === 'staging' || raw === 'stage' || raw === 'test') return 'staging'; if (raw === 'production' || raw === 'prod') return 'production'; if (raw === 'local' || raw === 'development' || raw === 'dev') return 'local'; if (nodeEnv === 'production') return 'production'; return 'local'; } const appEnv = resolveAppEnv(); const layers = appEnv === 'staging' ? [resolve(apiRoot, '.env.staging'), resolve(apiRoot, '.env.staging.local')] : appEnv === 'production' ? [resolve(apiRoot, '.env.production'), resolve(apiRoot, '.env.production.local')] : [resolve(apiRoot, '.env'), resolve(apiRoot, '.env.local')]; for (const file of layers) { if (existsSync(file)) { config({ path: file, override: true }); } } if (!process.env.NODE_ENV) { process.env.NODE_ENV = nodeEnv; } if (!process.env.APP_ENV) { process.env.APP_ENV = appEnv; }