Nest系列:从环境变量到工程化实践-2
文章目录
- @[toc]
- 一、环境搭建与基础配置
- 1.1 安装验证(新增完整示例)
- 1.2 多环境配置示例
- 二、模块化配置实战
- 2.1 根模块高级配置
- 2.2 数据库模块专用配置
- 三、配置获取最佳实践
- 3.1 类型安全获取示例
- 3.2 枚举工程化示例
- 四、高级场景示例
- 4.1 动态配置热更新
- 4.2 多层级配置合并
- 五、实用配置技巧
- 5.1 配置智能提示
- 5.2 多层级配置合并
- 六、项目结构建议
- 推荐配置目录结构
- 分层配置示例
- 七、调试技巧
- 7.1 配置查看命令
- 7.2 热重载配置(开发环境)
- 八、安全实践
- 8.1 敏感信息加密
文章目录
- @[toc]
- 一、环境搭建与基础配置
- 1.1 安装验证(新增完整示例)
- 1.2 多环境配置示例
- 二、模块化配置实战
- 2.1 根模块高级配置
- 2.2 数据库模块专用配置
- 三、配置获取最佳实践
- 3.1 类型安全获取示例
- 3.2 枚举工程化示例
- 四、高级场景示例
- 4.1 动态配置热更新
- 4.2 多层级配置合并
- 五、实用配置技巧
- 5.1 配置智能提示
- 5.2 多层级配置合并
- 六、项目结构建议
- 推荐配置目录结构
- 分层配置示例
- 七、调试技巧
- 7.1 配置查看命令
- 7.2 热重载配置(开发环境)
- 八、安全实践
- 8.1 敏感信息加密
一、环境搭建与基础配置
1.1 安装验证(新增完整示例)
# 安装后检查控制台输出
$ npm install @nestjs/config
+ @nestjs/config@9.0.0
added 1 package in 2s
# 验证导入能力
// app.module.ts
import { ConfigModule } from '@nestjs/config'; // 无报错即成功
# 查看版本信息
$ npm list @nestjs/config
└─ @nestjs/config@9.0.0
1.2 多环境配置示例
/
├── .env # 基础配置
├── .env.dev # 开发环境
├── .env.stage # 预发布环境
└── .env.prod # 生产环境
动态加载实现:
// app.module.ts
ConfigModule.forRoot({
envFilePath: [
`.env.${process.env.NODE_ENV}`, // 按环境加载
'.env' // 默认配置
],
expandVariables: true // 支持变量嵌套
})
变量嵌套示例:
# .env
BASE_URL=/api/v1
USER_SERVICE=${BASE_URL}/users
二、模块化配置实战
2.1 根模块高级配置
// app.module.ts
ConfigModule.forRoot({
envFilePath: [
`.env.${process.env.NODE_ENV}`, // 动态加载环境文件
'.env' // 默认配置
],
isGlobal: true,
cache: true, // 启用配置缓存
expandVariables: true // 支持变量扩展
});
2.2 数据库模块专用配置
// database.config.ts
export default registerAs('database', () => ({
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT, 10) || 5432,
ssl: process.env.NODE_ENV === 'production'
}));
// database.module.ts
@Module({
imports: [
ConfigModule.forFeature(databaseConfig)
]
})
export class DatabaseModule {}
三、配置获取最佳实践
3.1 类型安全获取示例
// config.service.ts
getDatabaseConfig() {
return {
host: this.configService.get<string>('DB_HOST'),
port: this.configService.get<number>('DB_PORT', 5432), // 带默认值
timeout: this.configService.getOrThrow<number>('API_TIMEOUT') // 强制存在
};
}
3.2 枚举工程化示例
// config.enum.ts
export enum ConfigKey {
Database = 'database', // 对应注册的命名空间
Redis = 'redis'
}
export enum DatabaseKey {
Host = 'host',
Port = 'port'
}
// user.service.ts
const redisConfig = this.configService.get(ConfigKey.Redis);
const dbPort = this.configService.get(`${ConfigKey.Database}.${DatabaseKey.Port}`);
四、高级场景示例
4.1 动态配置热更新
// 监听配置变化
constructor(private configService: ConfigService) {
configService.get('FEATURE_FLAG').subscribe(value => {
this.updateFeatureFlags(value);
});
}
4.2 多层级配置合并
# 支持YAML风格嵌套
DATABASE__HOST=cluster.db.example.com
DATABASE__OPTIONS__POOL_SIZE=10
DATABASE__OPTIONS__TIMEOUT=30
// 获取嵌套配置
const poolSize = configService.get('database.options.poolSize');
五、实用配置技巧
5.1 配置智能提示
// app.config.ts
export default registerAs(ConfigNamespace.App, () => ({
env: process.env.NODE_ENV,
port: parseInt(process.env.PORT, 10) || 3000,
enableSwagger: process.env.SWAGGER_ENABLED === 'true'
}));
// 使用时获得类型提示
this.configService.get(ConfigNamespace.App).enableSwagger
5.2 多层级配置合并
// 支持对象展开语法
const config = this.configService.get('database.connections.master');
六、项目结构建议
推荐配置目录结构
src/
├─ config/
│ ├─ app.config.ts # 应用基础配置
│ ├─ database.config.ts # 数据库配置
│ ├─ auth.config.ts # 认证配置
│ └─ validate.ts # 校验逻辑
├─ modules/
│ └─ ... # 业务模块
分层配置示例
// auth.config.ts
export default registerAs('auth', () => ({
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN || '1h',
refreshExpires: process.env.JWT_REFRESH_EXPIRES || '7d'
}));
// app.config.ts
export default registerAs('app', () => ({
env: process.env.NODE_ENV,
port: parseInt(process.env.PORT, 10) || 3000
}));
七、调试技巧
7.1 配置查看命令
# 查看加载的配置
curl http://localhost:3000/config-print
7.2 热重载配置(开发环境)
// main.ts
if (process.env.NODE_ENV === 'development') {
const configService = app.get(ConfigService);
fs.watch('.env', () => {
configService.reload();
console.log('配置文件已重新加载');
});
}
八、安全实践
8.1 敏感信息加密
// 使用crypto解密
import { createDecipheriv } from 'crypto';
const decrypt = (text: string) => {
const [iv, content] = text.split(':');
const decipher = createDecipheriv('aes-256-ctr', ENCRYPT_KEY, Buffer.from(iv, 'hex'));
return Buffer.concat([
decipher.update(Buffer.from(content, 'hex')),
decipher.final()
]).toString();
};
// 获取加密配置
const dbPassword = decrypt(configService.get('DB_PASSWORD'));