@buka/nestjs-配置
一个容易使用的NestJS配置模块,具有强大的特性和类型安全.
特征
- ✅ 类型安全配置: 配置校验
class-validator - ✅ 配置转换: 配置转换由
class-transformer - ✅ 弹性加载: 从多来源(env,文件等)装入配置
- ✅ 热重装入: 文件更改时自动重装配置( opt- in)
- ✅ 自动命名公约:自动处理命名样式(骆驼Case,蛇 case等)
- ✅ 可注射类: 配置类可以像其他提供者一样注入
- ✅ 全局配置: 定义配置一次, 随处使用
- ✅ 完美类型提示: 以优秀的 IDE 自动完成的完整类型脚本支持
安装
npm install @buka/nestjs-config
# or
yarn add @buka/nestjs-config
# or
pnpm add @buka/nestjs-config
快速启动
1. 创建配置类
使用装饰器定义您的配置 class-validator数字 :
// app.config.ts
import { Configuration } from "@buka/nestjs-config";
import { IsString, IsOptional, IsIn, IsIp } from "class-validator";
import { Split } from "@miaooo/class-transformer-split";
@Configuration()
export class AppConfig {
@IsIp()
host = "0.0.0.0"; // default value
@IsString()
@IsOptional()
cacheDir?: string;
@IsIn(["dev", "test", "prod"])
nodeEnv: string;
@Split(",")
brokers: string[];
}
2. 创建环境文件
创建一个 .env 在工程根中的文件 :
# .env
CACHE_DIR="./tmp"
NODE_ENV="dev"
BROKERS="test01.test.com,test02.test.com,test03.test.com"
[TIP]
@buka/nestjs-config自动转换命名样式.cache_dir, (中文(简体) ),CACHE_DIR, (中文(简体) ),cacheDir, (中文(简体) ),CacheDir, (中文(简体) ),cache-dir, (中文(简体) ),Cache_Dir被确认为相同的配置名称.
3. 进口配置模块
导入 ConfigModule 在您的 NestJS 应用程序中:
// app.module.ts
import { Module } from "@nestjs/common";
import { ConfigModule } from "@buka/nestjs-config";
@Module({
imports: [ConfigModule.register({ isGlobal: true })],
})
export class AppModule {}
默认, ConfigModule 加载配置从 process.env 财务报告和审定财务报表 .env 文档.
4. 注入配置
在服务中使用配置 :
// app.service.ts
import { Injectable } from "@nestjs/common";
import { AppConfig } from "./app.config";
@Injectable()
export class AppService {
constructor(private readonly appConfig: AppConfig) {}
getInfo() {
return `Host: ${this.appConfig.host}, Env: ${this.appConfig.nodeEnv}`;
}
}
配置
全球配置( 建议)
当需要在多个地方(NestJS模块、ORM配置、脚本)使用配置时,使用 ConfigModule.configure() 避免重复:
步骤1: 创建配置文件
// config/index.ts
import {
ConfigModule,
processEnvLoader,
yamlFileLoader,
} from "@buka/nestjs-config";
ConfigModule.configure({
loaders: [processEnvLoader(), yamlFileLoader("config.yaml")],
suppressWarnings: true,
});
步骤2:在 NestJS 模块中使用
// app.module.ts
import { Module } from "@nestjs/common";
import { ConfigModule } from "@buka/nestjs-config";
import "./config"; // Import configuration
@Module({
imports: [
ConfigModule.register({ isGlobal: true }), // Uses global config
],
})
export class AppModule {}
第3步:在外部文件中使用(ORM配置,脚本等)
// mikro-orm.config.ts
import { ConfigModule } from "@buka/nestjs-config";
import { DatabaseConfig } from "./config/database.config";
import "./config"; // Import configuration
export default (async function () {
await ConfigModule.preload(); // Uses global config
const config = await ConfigModule.getOrFail(DatabaseConfig);
return { ...config };
})();
[TIP] 全球配置的好处:
- 配置一次, 随处使用
- 之间没有重复
preload()财务报告和审定财务报表register()- 保证您的申请的一致性
- 可以在需要时通过直接传递选项来覆盖设置
配置选项
interface ConfigModuleOptions {
/**
* Configuration loaders (default: processEnvLoader + .env file)
*/
loaders?: (string | ConfigLoader)[];
/**
* Suppress warning messages
*/
suppressWarnings?: boolean;
/**
* Enable debug logging
*/
debug?: boolean;
/**
* Manually specify config providers (usually auto-detected)
*/
providers?: Type[];
}
自定义装入器
您可以自定义配置的加载方式 :
import {
ConfigModule,
processEnvLoader,
dotenvLoader,
} from "@buka/nestjs-config";
ConfigModule.configure({
loaders: [
processEnvLoader(),
dotenvLoader(".env", { separator: "__", jsonParse: true }),
dotenvLoader(`.env.${process.env.NODE_ENV}`),
],
});
高级使用
嵌入式配置
import { Configuration } from "@buka/nestjs-config";
import { ValidateNested, Type } from "class-transformer";
import { IsString } from "class-validator";
export class DatabaseConfig {
@IsString()
host: string; // DATABASE__HOST
@IsString()
password: string; // DATABASE__PASSWORD
}
@Configuration()
export class AppConfig {
@ValidateNested()
@Type(() => DatabaseConfig)
database: DatabaseConfig;
}
环境变量: DATABASE__HOST=localhost, (中文(简体) ), DATABASE__PASSWORD=secret
配置前缀
使用 @Configuration(prefix) 在所有属性中添加前缀:
import { Configuration } from "@buka/nestjs-config";
import { IsString } from "class-validator";
@Configuration("mysql.master")
export class MysqlConfig {
@IsString()
host: string; // MYSQL__MASTER__HOST
}
绘图 :
process.env数字 :MYSQL__MASTER__HOST.env文件 :MYSQL__MASTER__HOST- JSON文件 :
{ mysql: { master: { host: "..." } } }
自定义配置密钥
使用 @ConfigKey() 以覆盖属性名称 :
import { Configuration, ConfigKey } from "@buka/nestjs-config";
import { IsString } from "class-validator";
@Configuration("mysql")
export class MysqlConfig {
@ConfigKey("DATABASE_HOST")
@IsString()
host: string; // Now reads from DATABASE_HOST instead of MYSQL__HOST
}
[注]
@ConfigKey(name)覆盖前缀@Configuration(prefix)
预装配置( 外巢JS)
使用 ConfigModule.preload() 在 NestJS 初始化前装入配置 :
// database-migration.ts
import { ConfigModule } from "@buka/nestjs-config";
import { DatabaseConfig } from "./config/database.config";
import "./config"; // Import global configuration
async function migrate() {
await ConfigModule.preload(); // Uses global config
// Get configuration
const config = await ConfigModule.getOrFail(DatabaseConfig);
// Use config for migration...
}
模块集成
使用 ConfigModule.inject()数字 :
import { Module } from "@nestjs/common";
import { ConfigModule, Configuration } from "@buka/nestjs-config";
import { LoggerModule } from "nestjs-pino";
import { IsIn } from "class-validator";
@Configuration("logger")
class LoggerConfig {
@IsIn(["fatal", "error", "warn", "info", "debug", "trace"])
level: string = "info";
}
@Module({
imports: [
ConfigModule.register({ isGlobal: true }),
// Using ConfigModule.inject() - Simple and clean
ConfigModule.inject(LoggerConfig, LoggerModule, (config) => ({
pinoHttp: { level: config.level },
})),
],
})
class AppModule {}
配置热重装入
该模块支持热重装配置文件,允许您的应用程序在不重启的情况下自动接取配置更改.
基本用途
启用热重装器 hotReload 选项 :
import {
ConfigModule,
dotenvLoader,
jsonFileLoader,
yamlFileLoader,
} from "@buka/nestjs-config";
@Module({
imports: [
ConfigModule.register({
isGlobal: true,
loaders: [
// Enable hot reload with default settings (file watcher)
dotenvLoader(".env", { hotReload: true }),
// Enable hot reload for JSON file
jsonFileLoader("./config.json", "utf-8", { hotReload: true }),
// Enable hot reload for YAML file
yamlFileLoader("./config.yaml", "utf-8", { hotReload: true }),
],
}),
],
})
export class AppModule {}
高级用途 - 监视类型和钩
您可以自定义每个加载器的表行为 :
ConfigModule.register({
loaders: [
// File system watch (default, recommended)
dotenvLoader(".env", {
hotReload: {
type: "watch", // Use chokidar file system watcher
debounceMs: 500, // Wait 500ms before reloading (default: 300ms)
onChange: async (newConfig) => {
console.log("Config file changed, new config:", newConfig);
},
onError: async (error) => {
console.error("Failed to reload config:", error);
},
},
}),
// Polling mode (for network drives or special filesystems)
jsonFileLoader("./config.json", "utf-8", {
hotReload: {
type: "interval", // Use polling instead of file watching
intervalMs: 5000, // Check every 5 seconds (default: 5000ms)
debounceMs: 300,
},
}),
],
});
手动重装
您也可以手动触发配置重装 :
import { ConfigModule } from "@buka/nestjs-config";
// In your service or controller
async reloadConfig() {
try {
await ConfigModule.reload();
return { message: "Configuration reloaded successfully" };
} catch (error) {
throw new Error(`Failed to reload config: ${error.message}`);
}
}
这在下列情况下是有用的:
- 配置程序更新( 不通过文件更改)
- 您需要根据需要重新装入配置( 例如, 管理端点)
- 测试配置变化
如何运作
- 每个加载器可以独立启用自设的热重装
- 当文件更改时, 加载器会触发全局配置重装
- 所有配置提供者实例都在原地更新
- 插入配置对象自动反映新值
- 如果验证失败, 旧配置会被保存( 回滚)
页:1
- 每个加载器都配置了热重装( 每个文件可选择输入)
- 支持两者
watch模式(文件系统事件)和interval模式(波澜) - 环境可变加载器
processEnvLoader) 不支持观看 - 每个加载器都有独立的去除( 默认: 300ms)
- 重新装入时仍然应用配置验证
- 手动重新装入
ConfigModule.reload()也提供
无等价 ConfigModule.inject()数字 :
@Module({
imports: [
ConfigModule.register({ isGlobal: true }),
// Using forRootAsync directly - More verbose
LoggerModule.forRootAsync({
inject: [LoggerConfig],
useFactory: (config: LoggerConfig) => ({
pinoHttp: { level: config.level },
}),
}),
],
})
class AppModule {}
如你所见, ConfigModule.inject() 为插入其他模块提供更清洁的语法.
高级: 输入附加选项
import { TypeOrmModule } from "@nestjs/typeorm";
@Configuration("database")
class DatabaseConfig {
@IsString()
host: string;
@IsNumber()
port: number;
@IsString()
database: string;
}
@Module({
imports: [
ConfigModule.register({ isGlobal: true }),
// With additional module options (e.g., multiple databases)
ConfigModule.inject(
DatabaseConfig,
TypeOrmModule,
{ name: "primary" }, // Additional options
(config) => config, // Config mapper (optional)
),
],
})
class AppModule {}
相当于:
TypeOrmModule.forRootAsync({
name: "primary",
inject: [DatabaseConfig],
useFactory: (config: DatabaseConfig) => config,
});
内置装入器
| 装入器 | 说明 |
|---|---|
processEnvLoader() | 装入自 process.env |
dotenvLoader(path, options?) | 装入 .env 文件使用 多腾v |
dotenvxLoader(path, options?) | 装入 .env 文件使用 @ dotenvx/ dotenvx (英语) |
jsonFileLoader(path) | 装入 JSON 文件 |
yamlFileLoader(path, encoding?) | 使用 YAML 文件装入 雅姆尔 |
tomlFileLoader(path, encoding?) | 使用 闪闪发光 |
自定义加载器示例
import { ConfigLoader, ConfigModuleOptions } from "@buka/nestjs-config";
import { readFileSync } from "fs";
export function customLoader(filepath: string): ConfigLoader {
return (options: ConfigModuleOptions) => {
const content = readFileSync(filepath, "utf-8");
// Parse and return configuration object
return JSON.parse(content);
};
}
解决问题
错误: "我的配置课中每个字段都缺失"
当使用 TypeScript 时可能发生这种情况 target 设置为 ES2021 或低一点.
解决方案1(建议)升级到 ES2022 或高于 tsconfig.json
解决方案2页:1 @ConfigKey() 每个财产的装饰:
import { Configuration, ConfigKey } from "@buka/nestjs-config";
@Configuration()
export class AppConfig {
@ConfigKey()
@IsIp()
host = "0.0.0.0";
@ConfigKey()
@IsIn(["dev", "test", "prod"])
nodeEnv: string;
}
错误: "Nest 找不到您的配置元素"
当一个配置类没有注入任何服务时会发生这种情况.
解决方案1: 使用 ConfigModule.get() 改为 app.get()数字 :
await ConfigModule.preload();
const config = await ConfigModule.get(YourConfig);
解决方案2: 手动注册配置类 :
@Module({
imports: [
ConfigModule.register({
isGlobal: true,
providers: [YourConfig],
}),
],
})
class AppModule {}
许可证
麻省理工学院