前言
- 以前文章里也能导入env但不是常规写法,经过研究后发现了比较优雅的写法。
原理
- nest官方提供的@nest/config确实让我们方便注入env的,但是我用法不太对,比如一开始的typeorm需要连接数据库,前面文章里直接forroot然后默认就走的ormconfig去连接编译后的文件,虽然效果也行,但用用别的方法也挺有趣的。
- 连接编译后的文件我还遇到个大坑,差点把我吓死,还好失败回滚了。就是ts实体编译后,然后我改变实体名,或者删掉实体,我本意就是不想让typeorm去操作那个实体,然后我开着同步,结果dist下的实体没删掉,依然跑去按实体上定义去删表,还好当时又有备份且又因为实体上有个类型和表上类型不一致导致失败回滚。
- 但是后来研究发现,在ts中导入的路径一样是使用编译后的实体,貌似typeorm不能解析编译前的实体,所以是否同步需要谨慎使用。
设置
- 直接启个项目,需要安装的那些就不用说了。
- 为了让typeorm不拿ormconfig的配置,我们需要使用typeormmodule的forRootAsync导入官方的config模块注入env参数。
- 制作个config.ts:
export default () => ({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
database: process.env.DB_DATABASE,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
logging: JSON.parse(process.env.DB_LOGGING),
sync: JSON.parse(process.env.DB_SYNC),
});
- env就直接写上对应的即可。
- appmodule下载入官方提供config并使用import和inject注入useFactory中,让typeorm拿到env参数:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import configuration from './config';
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (config: ConfigService) => {
return {
type: 'mysql',
host: config.get('DB_HOST'),
port: config.get('DB_PORT'),
database: config.get('DB_DATABASE'),
username: config.get('DB_USERNAME'),
password: config.get('DB_PASSWORD'),
logging: config.get('DB_LOGGING'),
synchronize: config.get('DB_SYNC'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
timezone: '+08:00',
};
},
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}