nest框架官方文档中使用的是本地文件配置,也就是@nestjs/config包。本地配置文件的好处是简单,但是对于一些更新较快的项目,难免会增加配置数据,曾经吃过不少配置文件的亏,在发布的时候很容易因为缺少配置文件直接把服务发挂了,或者直接在服务器上修改配置很容易修改错误导致服务发布失败。
集中的配置中心可以解决上面问题,但前提是搭建配置中心。因公司已经有了配置中心,所以直接使用即可。 但是会出现这样的问题:从配置中心获取数据库连接信息,再去连接会连接失败,因为在连接的时候还没有获取到配置信息。 先看代码再解释。
// main.tsimport { NestFactory } from '@nestjs/core';import { ExpressAdapter, NestExpressApplication } from '@nestjs/platform-express';import { AppModule } from './app.module';import { MyLogger } from './libs/mylog.service';import { join } from 'path';const Apollo = require('node-apollo');const dotenv = require('dotenv');async function bootstrap() {try {const root = join(__dirname, '../');let envFile = join(root, '.env') dotenv.config({ "path": envFile })const { APOLLO_APPID, APOLLO_ENV, APOLLO_HOST, APOLLO_NAMESPACE, APOLLO_PORT, APOLLO_TOKEN, APOLLO_ClUSTER } = process.env;let apolloEnv = {configServerUrl: `http://${APOLLO_HOST}:${APOLLO_PORT}`,appId: `${APOLLO_APPID}`,clusterName: `${APOLLO_ClUSTER}`,apolloEnv: `${APOLLO_ENV}`,token: `${APOLLO_TOKEN}`,namespaceName: [`${APOLLO_NAMESPACE}`] };// 获取到的配置信息let zmConf = await Apollo.remoteConfigService(apolloEnv);console.log(">>>>>>>main.config", zmConf); process.env = Object.assign(process.env, zmConf); } catch (err) {console.log(`获取环境变量异常:${err}`) }const app = await NestFactory.create<NestExpressApplication>(AppModule, new ExpressAdapter()); app.useLogger(app.get(MyLogger));await app.listen(3434, () => {const logger = new MyLogger('main.ts'); logger.debug(process.env.NODE_ENV, 'main.ts'); logger.log('server start on http://localhost:3434'); }); } bootstrap();复制代码
// app.module.ts@Module({imports: [// MongooseModule.forRoot(`mongodb://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_DATABASE}`),MongooseModule.forRootAsync({useFactory: () => ({uri: `mongodb://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_DATABASE}`}), }),// Nest can't resolve dependencies of the AppService (?). Please make sure that the argument ArticleService at index [0] is available in the AppModule context.// 在article.service中exports:[ArticleService]ArticleModule, LoggerModule,// HttpModule,], // 导入模块所需的导入模块列表controllers: [AppController], // 必须创建的一组控制器providers: [AppService, MyLogger], // 由 Nest 注入器实例化的提供者,并且可以在整个模块中共享})export class AppModule implements NestModule {// 中间件模块在此处添加,可以给某一部分增加中间件,如果要全局增加则在main.ts中使用app.use添加configure(consumer: MiddlewareConsumer) { consumer .apply()// .with('中间件参数').forRoutes('/*'); } }复制代码
使用MongooseModule.forRoot连接数据库肯定是不行的,需要改成异步的:
MongooseModule.forRootAsync({useFactory: () => ({uri: `mongodb://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_DATABASE}`}), }),复制代码
因为按照nodejs模块导入的顺序,main.ts中先导入AppModule,AppModule中连接数据库,此时main.ts中的Apollo配置还没获取到,所以就不能正常连接了。那么就只能使用动态连接方式咯。