nestjs的生命周期
nestjs的生命周期从上到下的顺序如下
- 客户端请求
- 中间件
middleware
- 全局中间件 -> 模块中间件
- 守卫
guards
- 全局守卫 -> 控制器守卫 -> 路由守卫
- 拦截器
interceptors
- (pre)全局拦截器 -> (pre)控制器拦截器 -> (pre)路由拦截器
- 管道
pipes
- 全局管道 -> 控制器管道 -> 路由管道 -> 路由参数管道
- 控制器
controllers
- 服务
providers
- 拦截器
interceptors
- (post)路由拦截器 -> (post)控制器拦截器 -> (post)全局拦截器
- 过滤器
filters
- 路由过滤器 -> 控制器过滤器 ->全局过滤器
- 响应回客户端
node配置环境变量
安装插件: npm i dotenv config cross-env -S
dotenv配置简单环境变量
新建.env
文件
TOKEN_SECRET=devTokenSecret
DATA_USERNAME=devDataUsername
编辑index.js
文件
require('dotenv').config()
console.log(process.env.TOKEN_SECRET) // devTokenSecret
console.log(process.env.TOKEN_SECRET) // devDataUsername
缺点:只能配置简单的环境变量
config搭配cross-env配置环境变量
cross-env能够在
process.env
注入一个属性NODE_ENV
编辑./package.json
{
"scripts": {
// 开发环境:console.log(process.env.NODE_ENV) 会打印:development
"dev": "cross-env NODE_ENV=development node ./index.js",
// 测试环境:console.log(process.env.NODE_ENV) 会打印:test
"test": "cross-env NODE_ENV=test node ./index.js",
// 生产环境:console.log(process.env.NODE_ENV) 会打印:production
"prod": "cross-env NODE_ENV=production node ./index.js"
},
}
创建config目录
,内部创建default.json
,development.json
,test.json
,production.json
,
当运行程序的时候
// default.json
{ "token": "", "database": { "host": "localhost", "port": 8080} }
// development.json
{ "token": "dev_token", "database": { "host": "localhost", "port": 8080} }
// test.json
{ "token": "test_token", "database": { "host": "11.111.111.11", "port": 8081} }
// production.json
{ "token": "prod_token", "database": { "host": "11.111.111.11", "port": 8082} }
config插件能够自动读取config下面的json配置文件,把
default.json
和对应开发模式的配置文件进行合并输出当你执行了
npm run test
,config插件会自动合并default.json
和test.json
配置
编辑index.js
文件
const config = require('config')
const dbConfig = config.get('database')
const token = config.get('token')
console.log(dbConfig, token)
nest配置环境变量
安装插件:npm i @nestjs/config dotenv cross-env -S
新建配置文件.env
DB_NAME=mysql
DB_PASSWORD=password
在app.module.ts
中导入全局配置ConfigModule
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true, // 需要配置这个属性才会全局生效
}),
UserModule,
],
})
export class AppModule {}
在子模块./user/user.controller.ts
中使用全局配置ConfigService
全局配置会自动读取
.env
的内容
import { ConfigService } from '@nestjs/config';
@Controller('user')
export class UserController {
constructor(
private configService: ConfigService,
) {}
@Get()
getUsers() {
const DB_NAME = this.configService.get('DB_NAME')
const DB_PASSWORD = this.configService.get('DB_PASSWORD')
console.log(DB_NAME, DB_PASSWORD); // 输出:mysql password
}
}
cross-env 配置环境读取不同的内容
在package.json
的命令中引入cross-env
配置不同的环境
"scripts": {
"start:dev": "cross-env NODE_ENV=development nest start --watch",
"start:prod": "cross-env NODE_ENV=production node dist/main",
},
在根目录新增加.env.development
和.env.production
, 修改app.module.ts
中ConfigModule
的配置
ConfigModule.forRoot({
isGlobal: true, // 需要配置这个属性才会全局生效
+ envFilePath: `./.env.${process.env.NODE_ENV}`, // 读取对应环境的配置文件
}),
增加如上配置后, 运行不同的命令会项目会读取对应环境的配置文件. 但是如果需要读取公共配置文件怎么办?
增加公共配置
修改app.module.ts
中ConfigModule
的配置
import * as dotenv from 'dotenv';
ConfigModule.forRoot({
isGlobal: true, // 需要配置这个属性才会全局生效
envFilePath: `./.env.${process.env.NODE_ENV}`, // 读取对应环境的配置文件
+ load: [() => dotenv.config({ path: '.env' })], // 读取`.env`文件作为公共配置
}),
增加load配置会读取
.env
文件作为公共配置和对应环境的配置合并
配置文件参数验证
安装插件:npm i joi -S
, joi文档
修改app.module.ts
中ConfigModule
的配置
import * as Joi from 'joi';
ConfigModule.forRoot({
isGlobal: true, // 需要配置这个属性才会全局生效
envFilePath: `./.env.${process.env.NODE_ENV}`, // 读取对应环境的配置文件
load: [() => dotenv.config({ path: '.env' })], // 读取`.env`文件作为公共配置
validationSchema: Joi.object({
DB_NAME: Joi.string().required(),
DB_PASSWORD: Joi.string().required(),
DB_PORT: Joi.number().default(3306),
DB_HOST: Joi.string().required().ip(),
}),
}),
命令行覆盖环境变量
在启动项目的时候可以灵活配置环境变量:npx cross-env DB_NAME=terminal_dbname npm run start:dev
在这里设置的
DB_NAME=terminal_dbname
会覆盖项目中的process.env.DB_NAME
值