NestJS udostępnia pakiet @nestjs/config do zarządzania konfiguracją i zmiennymi środowiskowymi w strukturyzowany, type-safe, wstrzykiwalny sposób. Ładuje pliki .env, waliduje konfigurację i udostępnia wartości w całej aplikacji za pośrednictwem wstrzykiwalnego ConfigService.
Konfiguracja ConfigModule
import { ConfigModule } from "@nestjs/config";
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true, // available app-wide without re-importing
envFilePath: ".env",
validationSchema: Joi.object({ // validate env vars at startup (fail fast)
DATABASE_URL: Joi.string().required(),
PORT: Joi.number().default(3000),
JWT_SECRET: Joi.string().required(),
}),
}),
],
})
export class AppModule {}
ConfigModule.forRoot() ładuje zmienne środowiskowe (z .env + środowiska procesu) i — co ważne — może walidować je za pomocą schematu (Joi), aby brakująca lub nieprawidłowa konfiguracja zawiesiła aplikację przy uruchomieniu z jasnym komunikatem błędu zamiast tajemniczo zawieść w czasie wykonania.
Odczytywanie konfiguracji za pośrednictwem ConfigService (wstrzykiwalnego)
@Injectable()
export class DatabaseService {
constructor(private configService: ConfigService) {} // inject ConfigService
connect() {
const url = this.configService.get<string>("DATABASE_URL");
const port = this.configService.get<number>("PORT", 3000); // with a default
}
}
Zamiast czytać process.env bezpośrednio wszędzie, wstrzykujesz ConfigService i wywołujesz get() — type-safe, testowalny i scentralizowany.
Konfiguracja z namespacami/typowana
// config/database.config.ts — group related config with registerAs
export default registerAs("database", () => ({
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT, 10),
}));
// load it: ConfigModule.forRoot({ load: [databaseConfig] })
// access it: configService.get("database.host")
Namespacowanie grupuje powiązane ustawienia i utrzymuje konfigurację zorganizowaną w miarę jej wzrostu.
Dlaczego nie po prostu używać process.env bezpośrednio?
✗ process.env scattered everywhere → hard to test, no validation, stringly-typed
✓ ConfigService → injectable (mockable in tests), validated at startup, typed,
centralized — the structured NestJS way
Sekrety i środowiska
✓ Keep secrets in .env (GITIGNORED) — commit a .env.example documenting required vars
✓ In production, inject config via the platform's env vars / secret manager
✓ Validate at startup so misconfiguration fails immediately with a clear message
Dlaczego to ważne
Prawidłowe zarządzanie konfiguracją jest niezbędne dla każdej rzeczywistej aplikacji — obsługa adresów URL baz danych, kluczy API, portów, sekretów i flag funkcji bezpiecznie i elastycznie w różnych środowiskach (dev, staging, production).
@nestjs/config NestJS zapewnia strukturyzowany, idiomatyczny sposób, aby to zrobić, i zrozumienie go jest ważną wiedzą codzienną.
Klucze przewagi nad bezpośrednim czytaniem process.env są znaczące: wstrzykiwalny ConfigService czyni konfigurację testowalną (mockowaną w testach) i scentralizowaną; walidacja przy uruchomieniu (ze schematem Joi) natychmiast wychwytuje brakującą lub zniekształconą konfigurację z jasnym komunikatem błędu zamiast mylącego błędu wykonania gdzieś głęboko w żądaniu; a namespacing utrzymuje rosnącą konfigurację zorganizowaną.
W połączeniu z najlepszą praktyką bezpieczeństwa przechowywania sekretów w ignorowanych przez gita plikach .env (i zatwierdzonym .env.example), daje to Ci bezpieczną, przenośną, walidowaną konfigurację.
Wiedzenie, jak skonfigurować ConfigModule, wstrzykać i używać ConfigService oraz walidować konfigurację, jest fundamentalne dla budowania produkcyjnych aplikacji NestJS i odzwierciedla profesjonalną praktykę back-end.
