Nestjs开发环境和生产环境的配置
原创
©著作权归作者所有:来自51CTO博客作者水痕01的原创作品,请联系作者获取转载授权,否则将追究法律责任
这篇是Nest微服务训练营基础篇一小节,训练营大概会有100多篇关于Nest实操的文字,本小节讲述开发过程中环境变量的区分,更多精彩文章关注我,
一、简单的使用.env
文件来实现配置文件
npm install dotenv
npm install @types/dotenv -D
- 2、根目录下创建一个
.env
的文件,如果是线上项目将.env
加入到.gitignore
中,如果是自己学习阶段无所谓 - 3、在
.env
文件中写入端口号及项目前缀
import 'dotenv/config'; // 这行是关键代码
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
export const IS_DEV = process.env.NODE_ENV !== 'production';
const PORT = process.env.PORT || 8080;
const PREFIX = process.env.PREFIX || '/';
async function bootstrap() {
const logger: Logger = new Logger('main.ts');
const app = await NestFactory.create(AppModule, {
// 开启日志级别打印
logger: IS_DEV ? ['log', 'debug', 'error', 'warn'] : ['error', 'warn'],
});
await app.listen(PORT, () => {
logger.log(`服务已经启动,接口请访问:http://wwww.localhost:${PORT}/${PREFIX}`);
});
}
bootstrap();
- 5、这种方式使用简单,只要安装两个依赖包就可以,但是不足之处在于不能区分开发环境和生产环境的配置,都统一写在
.env
文件中,每次要使用的时候还要process.env.xx
的方式来使用,下面会介绍如何区分开发环境和生产环境使用不同的配置文件,方便环境中变量的管理
二、使用config
的依赖包来方便获取配置文件中的配置
npm install @nestjs/config
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: ['.env'],
}),
],
controllers: [AppController],
providers: [AppService, Logger],
})
export class AppModule {}
- 3、在需要获取配置的地方使用
ConfigService
提供一个get
方法来获取
console.log(this.configService.get('PORT'), '当前的端口');
- 4、说明下如果使用了
@nestjs/config
这个包,在main.ts
文件首部可以不用引入import 'dotenv/config'
三、使用.env
的方式来区分环境
- 1、在项目根目录下分别创建
.env
、.env.dev
、.env.prod
文件并且在ConfigModule
中加载
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: ['.env.dev', '.env', '.env.prod'],
}),
],
controllers: [AppController],
providers: [AppService, Logger],
})
export class AppModule {}
- 2、根据官网上的介绍是前面的优先级比后面的优先级高,简单的理解就是在获取的时候会先查找
envFilePath
数组的第一项,里面有就直接返回当前的,如果没有就会查找第二个,根据这个原理我们可以重新来编排下envFilePath
数组项 - 3、安装依赖包来配置设置当前环境,上面使用
process.env.NODE_ENV
已经不能判断当前是什么环境
- 4、手动配置启动环境的配置,修改
package.json
文件启动命令
...
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "cross-env RUNNING_ENV=dev nest start",
"start:dev": "cross-env RUNNING_ENV=dev nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "cross-env RUNNING_ENV=prod node dist/main",
}
...
- 5、重新定义获取当前环境的变量,注意不能定义在
main.ts
中,必须定义在app.module.ts
文件中
export const IS_DEV = process.env.RUNNING_ENV !== 'prod';
import { Logger, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
let envFilePath = ['.env'];
export const IS_DEV = process.env.RUNNING_ENV !== 'prod';
if (IS_DEV) {
envFilePath.unshift('.env.dev');
} else {
envFilePath.unshift('.env.prod');
}
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath,
}),
],
controllers: [AppController],
providers: [AppService, Logger],
})
export class AppModule {}
import { AppModule, IS_DEV } from './app.module';
const PORT = process.env.PORT || 8080;
const PREFIX = process.env.PREFIX || '/';
console.log(`Port: ${PORT}`, IS_DEV);
- 7、尝试从
.env.dev
文件中删除PORT
的时候控制台会打印出.env
的端口,如果加上会打印出.env.dev
的端口 - 8、关于
.env
、.env.dev
、.env.prod
几个文件说明
-
.env
文件存放一些通用的配置,在开发环境和生产环境都保持一样的 -
.env.dev
文件存放开发环境的配置 -
.env.prod
文件存放生产部署需要的配置
- 9、关于使用
.env
来配置不同环境的代码参考,代码地址
四、使用yml
文件来做配置文件
- 3、在根目录下创建
application.dev.yml
和application.prod.yml
两个文件来区分配置开发环境和生产环境,并且添加值.gitignore
文件中 - 4、创建一个文件用来读取配置
utils/config.ts
import { parse } from 'yaml';
import * as path from 'path';
import * as fs from 'fs';
// 获取项目运行环境
export const getEnv = () => {
return process.env.RUNNING_ENV;
};
export const IS_DEV = getEnv() === 'dev';
// 读取项目配置
export const getConfig = () => {
const environment = getEnv();
console.log(environment, '当前运行的环境');
const yamlPath = path.join(process.cwd(), `./application.${environment}.yml`);
const file = fs.readFileSync(yamlPath, 'utf8');
const config = parse(file);
return config;
};
- 5、修改
app.module.ts
文件的配置
import { Logger, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { getConfig } from './utils';
@Module({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: false, // 忽视默认读取.env的文件配置
isGlobal: true, // 全局注入
load: [getConfig], // 加载配置文件
}),
],
controllers: [AppController],
providers: [AppService, Logger],
})
export class AppModule {}
- 6、修改
main.ts
文件,之前直接从process.env.
的方式获取不到配置项目了,要改为方法的调用方式
import { getConfig, IS_DEV } from './utils';
const config = getConfig();
const PORT = config.PORT || 8080;
const PREFIX = config.PREFIX || '/';
... 省去100行代码
- 7、在别的地方要获取配置文件和之前一样的使用
this.configService.get('PORT')
的方式来获取 - 8、本小节代码见,代码地址