所需依赖
bash
复制代码
pnpm i @nestjs/config js-yaml lodash
pnpm i @types/js-yaml @types/lodash cross-env -D
目录结构
bash
复制代码
|- config
| |- config.yaml # 通用配置文件
| |- config.local.yaml # 通用配置文件本地版(不会被 Git 记录)
| |- config.development.yaml # 开发环境配置文件版
| |- config.development.local.yaml # 开发环境配置文件版(不会被 Git 记录)
| |- config.production.yaml # 生产配置文件本地版
| |- config.production.local.yaml # 生产配置文件本地版(不会被 Git 记录)
|- src
| |- common
| |- config.module.ts # 自定义的环境配置模块
| |- app.module.ts
|- .gitignore
|- nest-cli.json
涉及文件
1、package.json
json
复制代码
{
"scripts": {
"build": "cross-env NODE_ENV=production nest build",
"start": "cross-env NODE_ENV=development nest start",
"start:dev": "cross-env NODE_ENV=development nest start --watch",
"start:debug": "cross-env NODE_ENV=development nest start --debug --watch",
"start:prod": "node dist/main",
"start:deploy": "node main.js",
},
"dependencies": {
"@nestjs/config": "^4.0.2",
"js-yaml": "^4.1.1",
"lodash": "^4.17.21"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/lodash": "^4.17.21",
"cross-env": "^10.1.0"
}
}
2、config.module.ts
ts
复制代码
import { join } from 'path'
import jsYaml from 'js-yaml'
import { merge } from 'lodash'
import { Module } from '@nestjs/common'
import { readFileSync, existsSync } from 'fs'
import { ConfigModule as NestConfigModule } from '@nestjs/config'
@Module({
imports: [
NestConfigModule.forRoot({
load: [configuration],
isGlobal: true,
cache: true,
}),
],
})
export class ConfigModule {}
/**
* 读取指定路径的 YAML 配置文件并转为对象类型
* @param filePath YAML 配置文件的路径
* @returns 解析后的配置对象,如果文件不存在则返回空对象
*/
function loadConfig(filePath: string): Record<string, any> {
return existsSync(filePath) ? (jsYaml.load(readFileSync(filePath, 'utf-8')) as Record<string, any>) : {}
}
/**
* 配置加载核心函数:读取并合并多环境 YAML 配置文件
*
* 功能说明:
* - 根据 NODE_ENV 区分开发/生产环境,确定配置文件存放目录
* - 按优先级读取4类 YAML 配置文件(通用→通用本地→环境→环境本地)
* - 深度合并配置对象,后续配置会覆盖前面的同名嵌套属性
* - 最终返回合并后的完整配置,供 NestJS ConfigModule 使用
*
* 配置优先级(从低到高,后面覆盖前面):
* - config.yaml < config.local.yaml < config.{NODE_ENV}.yaml < config.{NODE_ENV}.local.yaml
*/
function configuration() {
// 从环境变量中获取当前运行环境,默认为开发环境
const { NODE_ENV = 'development' } = process.env
// 确定配置文件的存放目录
// - 开发环境: 读取项目根目录下的 config 文件夹
// - 生产环境: 直接读取当前文件所在的目录
const CONFIG_DIR_PATH = NODE_ENV === 'development' ? join(process.cwd(), 'config') : __dirname
// 定义各类配置文件的路径
// 通用配置文件(所有环境共享的基础配置)
const YAML_COMMON_CONFIG_PATH = join(CONFIG_DIR_PATH, 'config.yaml')
// 通用本地配置文件(本地开发覆盖通用配置的个性化设置,不应提交到代码仓库)
const YAML_COMMON_CONFIG_LOCAL_PATH = join(CONFIG_DIR_PATH, 'config.local.yaml')
// 特定环境的配置文件(针对当前环境的专用配置,如开发/生产环境的差异配置)
const YAML_ENV_CONFIG_PATH = join(CONFIG_DIR_PATH, `config.${NODE_ENV || 'development'}.yaml`)
// 特定环境的本地配置文件(本地覆盖当前环境配置的个性化设置,不应提交到代码仓库)
const YAML_ENV_CONFIG_LOCAL_PATH = join(CONFIG_DIR_PATH, `config.${NODE_ENV || 'development'}.local.yaml`)
// 读取各类配置文件的内容
const COMMON_CONFIG = loadConfig(YAML_COMMON_CONFIG_PATH)
const COMMON_CONFIG_LOCAL = loadConfig(YAML_COMMON_CONFIG_LOCAL_PATH)
const ENV_CONFIG = loadConfig(YAML_ENV_CONFIG_PATH)
const ENV_CONFIG_LOCAL = loadConfig(YAML_ENV_CONFIG_LOCAL_PATH)
// 深度合并配置,后面的配置会覆盖前面的同名配置
// 这样既保证了基础配置的通用性,又允许环境和本地配置进行个性化定制
return merge(COMMON_CONFIG, COMMON_CONFIG_LOCAL, ENV_CONFIG, ENV_CONFIG_LOCAL)
}
3、app.module.ts
ts
复制代码
import { Module } from '@nestjs/common'
import { ConfigModule } from './common/config.module.ts'
@Module({
imports: [ConfigModule]
})
export class AppModule {}
4、.gitignore
bash
复制代码
# dotenv environment variable files
.env.local
*.local.yaml
5、nest-cli.json
json
复制代码
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
{ "include": "../package.json", "outDir": "./dist/package.json" },
{ "include": "../pnpm-lock.yaml", "outDir": "./dist/pnpm-lock.yaml" },
{ "include": "../config/config.yaml", "outDir": "./dist" }
],
"deleteOutDir": true,
"builder": "webpack"
},
"generateOptions": {
"flat": false,
"spec": false
}
}
使用介绍
1、service 服务使用
ts
复制代码
import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
@Injectable()
export class LoginService {
constructor(private readonly configService: ConfigService) {}
public testEnvConfig() {
const dbHost = this.configService.get<string>('database.host','localhost')
}
}
2、main.ts 中使用
ts
复制代码
import { AppModule } from './app.module'
import { ConfigService } from '@nestjs/config'
async function bootstrap() {
const app = await NestFactory.create(AppModule)
// 从应用容器中获取配置服务实例,由于 ConfigModule 被设置为全局模块,这里可以直接获取
const configService = app.get(ConfigService)
const serverPort = configService.get<number>('server.port', 3000)
// 启动应用并监听配置中指定的端口
// 这一步会启动 HTTP 服务器,使应用开始接收外部请求
await app.listen(serverPort)
// 打印服务启动信息,方便开发者在终端查看访问地址
console.log('\n--------------------------------------------------')
console.log(`➜ Local: http://localhost:${serverPort}`)
console.log('--------------------------------------------------')
}
// 调用启动函数,启动应用
bootstrap()