Nest + Fastify + fasity-next + TypeOrm 找不到 next() 函数

Nest + Fastify + fasity-next + TypeOrm cannot find next() function

我正在尝试使用 fastify-next 插件使用 Fastify 和 Next 初始化 Nest,一切正常,直到我集成了 TypeOrm (MongoDB)。当 Nest 加载 AppModule 时,它​​会抛出一个错误,指出 fastify-next 插件初始化后 fastify 实例中找不到 .next() 函数。

代码

// main.ts
async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  await app.init();

  const configService = app.get<ConfigService<IConfigTypes>>(ConfigService);
  const appConfig = configService.get<IAppConfig>('app');

  const fastify = await app.register(fastifyNext, {
    dev: appConfig.isDev,
    dir: appConfig.clientPath,
  });

  fastify.after(() => {
    appConfig.staticRoutes.forEach((page) => fastify.next(page));
  });

  await app.listen(appConfig.port);
  Logger.log(` Server is running on port ${appConfig.port}`, 'Bootstrap');
}
bootstrap();
// app.module.ts
@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
      isGlobal: true,
      cache: true,
      load: [appConfig, shopifyConfig, databaseConfig],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService<IConfigTypes>) => {
        const dbConfig = configService.get<IDatabaseConfig>('database');
        const { type, host, base, user, pass } = dbConfig;

        let url = 'mongodb+srv://';
        url += `${user}:${pass}@${host}/${base}`;
        url += '?retryWrites=true&w=majority';

        return {
          type,
          url,
          entities: [join(__dirname, '**/**.entity{.ts,.js}')],
          synchronize: true,
          useNewUrlParser: true,
          logging: true,
        };
      },
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

控制台出错:

[8:45:52 AM] File change detected. Starting incremental compilation...

[8:45:52 AM] Found 0 errors. Watching for file changes.

[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [NestFactory] Starting Nest application...
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] AppModule dependencies initialized +26ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] ConfigHostModule dependencies initialized +1ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 26331  - 08/23/2021, 8:45:55 AM     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +2361ms
[Nest] 26331  - 08/23/2021, 8:45:55 AM     LOG [NestApplication] Nest application successfully started +5ms

/dir/to/project/node_modules/avvio/boot.js:533
      res = func()
            ^
TypeError: fastify.next is not a function
    at /dir/to/project/src/server/main.ts:30:54 ===> appConfig.staticRoutes.forEach((page) => fastify.next(page));

我的临时解决方案是等到 .next() 函数在 fastify 实例中可用,然后 运行 代码。但我认为这不是解决这个问题的正确方法。

代码:

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  await app.init();

  const configService = app.get<ConfigService<IConfigTypes>>(ConfigService);
  const appConfig = configService.get<IAppConfig>('app');

  const fastify = await app.register(fastifyNext, {
    dev: appConfig.isDev,
    dir: appConfig.clientPath,
  });

  await new Promise((res) => {
    const launch = async () => {
      if (!fastify.next) {
        setTimeout(launch, 200);
        return;
      }

      appConfig.staticRoutes.forEach((page) => fastify.next(page));
      await app.listen(appConfig.port);
      Logger.log(` Server is running on port ${appConfig.port}`, 'Bootstrap');
      res(null);
    };

    launch();
  });
}
bootstrap();

如果我从 AppModule 中删除 TypeOrmModule 错误消失,我认为错误是由模块 forRootAsync.

的异步加载引起的

有人知道如何解决吗?如果您知道解决此问题的更好解决方案,请帮助我。谢谢!

我找到的解决方案是从 Nest.js HTTPAdapter 获取 FastifyInstance 并使用该实例注册插件。另外,我使用 promise 等到 fastify 注册插件然后监听端口(启动应用程序)。

  await app.init();

  const configService = app.get<ConfigService<IConfigTypes>>(ConfigService);
  const appConfig = configService.get<IAppConfig>('app');
  const fastify = app.getHttpAdapter().getInstance() as FastifyInstance;

  await new Promise((resolve) => {
    fastify
      .register(fastifyNext, {
        dev: appConfig.isDev,
        dir: appConfig.clientPath,
      })
      .after(async () => {
        appConfig.staticRoutes.forEach((route) => fastify.next(route));
        resolve(null);
      });
  });

  await app.listen(appConfig.port);
  Logger.log(` Server is running on port ${appConfig.port}`, 'Bootstrap');