我试图使用fasttify - Next插件初始化Nest,一切都很好,直到我集成了TypeOrm (MongoDB)。当Nest加载AppModule时,它会抛出一个错误,说在fastify-next
插件初始化后,.next()
函数没有在fastify
实例中找到。
// 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获得fasttifyinstance,并使用该实例来注册插件。此外,我使用了一个承诺等待,直到fasttify注册插件,然后监听端口(启动应用程序)。
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');