安装
pnpm i --save @nestjs/config
@nestjs/config 内部使用 dotenv 实现。
配置
一般会在根模块AppModal中导入,并使用.forRoot()静态方法导入它的配置
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule.forRoot()],
})
export class AppModule {}
以上配置会默认载入并解析一个 .env 文件,从.env文件和process.env合并环境变量键值对,并将结果存储到一个可以通过ConfigService访问的私有结构。forRoot()方法注册了ConfigService提供者,后者提供了一个get()方法来读取这些解析/合并的配置变量。由于@nestjs/config依赖dotenv,它使用该包的规则来处理冲突的环境变量名称。当一个键同时作为环境变量(例如,通过操作系统终端如export DATABASE_USER=test导出)存在于运行环境中以及.env文件中时,以运行环境变量优先。
.env 例子
DATABASE_USER=root
DATABASE_PASSWORD=test
自定义env文件路径
ConfigModule.forRoot({
envFilePath: '.development.env',
});
// 多个
ConfigModule.forRoot({
envFilePath: ['.env.development.local', '.env.development'],
});
禁止加载环境变量
ConfigModule.forRoot({
ignoreEnvFile: true,
});
全局使用配置
ConfigModule.forRoot({
isGlobal: true,
});
使用yaml方式配置
安装
npm i js-yaml -S
npm i @types/js-yaml -D
在src文件夹下创建一个config目录来放各个环境的配置,这里创建3个环境dev/prod/test
config/index.ts
import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';
const configFileName = {
development: 'dev',
test: 'test',
production: 'prod',
};
const env = process.env.NODE_ENV;
export default () => {
return yaml.load(
readFileSync(join(__dirname, `./${configFileName[env]}.yml`), 'utf8'),
) as Record<string, any>;
};
yml格式的配置文件比如dev.yml
# 数据库配置
db:
mysql:
host: 'localhost'
username: 'root'
password: '123456'
database: 'kapok'
port: 3306
charser: 'utf8mb4'
logger: 'advanced-console'
logging: true
multipleStatements: true
dropSchema: false
synchronize: true
supportBigNumbers: true
bigNumberStrings: true
app.module.ts中配置导入yml配置
import configuration from './config/index';
@Module({
imports: [
ConfigModule.forRoot({
cache: true,
load: [configuration],
isGlobal: true,
}),
],
controllers: [],
providers: [],
})
现在如果启动项目的话,大概率yml文件会找不到而报错,此时还需要去配置下cli的配置文件nest-cli.json
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
"**/*.yml"
],
"deleteOutDir": true,
"watchAssets": true
}
}
配合 cross-env
pnpm i cross-env -D
修改对应环境的脚本命令
"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": "nest start --debug --watch",
"start:prod": "cross-env NODE_ENV=production node dist/main",
}
使用配置
import { ConfigService } from '@nestjs/config';
@Controller('user')
export class UserController {
constructor(
private readonly userService: UserService,
private configService: ConfigService,
) {}
@Get()
findAll() {
console.log('configService===', this.configService.get('db'));
return this.userService.findAll();
}
配合Joi
pnpm i joi -S
假设去校验开发环境的变量配置和服务启动的端口,可以在配置服务的地方这样做
ConfigModule.forRoot({
cache: true,
load: [configuration],
isGlobal: true,
validationSchema: Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'production', 'test')
.default('development'),
PORT: Joi.number().default(3000),
}),
validationOptions: {
// 控制是否允许环境变量中未知的键 默认为true
allowUnknown: true,
// 在遇到第一个错误时就停止验证,如果为false就返回所有错误,默认为false
abortEarly: true,
},
})
这里有个需要注意的地方,引入joi的时候如果是使用esm的方式就需要全部重命名导入
import * as Joi from 'joi'