99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

NestJS 延遲加載模塊

2023-09-08 14:52 更新

默認(rèn)情況下,模塊是預(yù)先加載的,這意味著一旦應(yīng)用加載,所有模塊也會加載,無論它們是否立即需要。 雖然這對大多數(shù)應(yīng)用來說都很好,但它可能成為在 無服務(wù)器環(huán)境 中運行的應(yīng)用/工作程序的瓶頸,其中啟動延遲 ("冷啟動") 至關(guān)重要。

延遲加載可以通過僅加載特定無服務(wù)器函數(shù)調(diào)用所需的模塊來幫助減少引導(dǎo)時間。 此外,你還可以在無服務(wù)器功能為 "warm" 時異步加載其他模塊,以進(jìn)一步加快后續(xù)調(diào)用的引導(dǎo)時間(延遲模塊注冊)。

提示如果你熟悉 Angular 框架,你可能以前見過 "延遲加載模塊" 術(shù)語。 請注意,此技術(shù)是 Nest 中的 功能不同,因此請將其視為具有相似命名約定的完全不同的功能。
警告請注意,生命周期鉤子方法 不會在延遲加載的模塊和服務(wù)中調(diào)用。

入門

為了按需加載模塊,Nest 提供了 LazyModuleLoader 類,可以以正常方式注入到類中:

cats.service.ts

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
提示LazyModuleLoader 類是從 @nestjs/core 包中導(dǎo)入的。

或者,你可以從應(yīng)用引導(dǎo)程序文件 (main.ts) 中獲取對 LazyModuleLoader 提供程序的引用,如下所示:

// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);

有了這個,你現(xiàn)在可以使用以下結(jié)構(gòu)加載任何模塊:

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
提示"Lazy-loaded" 模塊在第一個 LazyModuleLoader#load 方法調(diào)用時是 cached。 這意味著,每次連續(xù)嘗試加載 LazyModule 都將是 非常快,并將返回一個緩存實例,而不是再次加載模塊。 Load "LazyModule" attempt: 1 time: 2.379ms Load "LazyModule" attempt: 2 time: 0.294ms Load "LazyModule" attempt: 3 time: 0.303ms 此外,"lazy-loaded" 模塊與那些在應(yīng)用引導(dǎo)程序中預(yù)加載的模塊以及稍后在你的應(yīng)用中注冊的任何其他惰性模塊共享相同的模塊圖。

其中 lazy.module.ts 是導(dǎo)出 常規(guī) Nest 模塊 的 TypeScript 文件(不需要額外更改)。

LazyModuleLoader#load 方法返回 模塊參考(屬于 LazyModule),它允許你導(dǎo)航內(nèi)部提供者列表并使用其注入令牌作為查找鍵獲取對任何提供者的引用。

例如,假設(shè)我們有一個具有以下定義的 LazyModule:

@Module({
  providers: [LazyService],
  exports: [LazyService],
})
export class LazyModule {}
提示延遲加載的模塊不能注冊為 全局模塊,因為它根本沒有意義(因為它們是延遲注冊的,當(dāng)所有靜態(tài)注冊的模塊已經(jīng)實例化時按需注冊)。 同樣,正確注冊 全局增強(qiáng)子(守衛(wèi)/攔截器等)不管用。

有了這個,我們可以獲得對 LazyService 提供者的引用,如下所示:

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);

const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
警告如果你使用 Webpack,請確保更新你的 tsconfig.json 文件 - 將 compilerOptions.module 設(shè)置為 "esnext" 并添加 compilerOptions.moduleResolution 屬性并將 "node" 作為值: { "compilerOptions": { "module": "esnext", "moduleResolution": "node", ... } } 設(shè)置這些選項后,你將能夠利用 代碼拆分 功能。

延遲加載控制器、網(wǎng)關(guān)和解析器

由于 Nest 中的控制器(或 GraphQL 應(yīng)用中的解析器)表示路由/路徑/主題(或查詢/突變)的集合,因此你 不能延遲加載它們 使用 LazyModuleLoader 類。

警告在延遲加載模塊中注冊的控制器、resolvers 和 gateways 將不會按預(yù)期運行。 同樣,你不能按需注冊中間件函數(shù)(通過實現(xiàn) MiddlewareConsumer 接口)。

例如,假設(shè)你正在使用底層的 Fastify 驅(qū)動程序(使用 @nestjs/platform-fastify 包)構(gòu)建一個 REST API(HTTP 應(yīng)用)。 Fastify 不允許你在應(yīng)用準(zhǔn)備好/成功監(jiān)聽消息后注冊路由。 這意味著即使我們分析了在模塊控制器中注冊的路由映射,也無法訪問所有延遲加載的路由,因為無法在運行時注冊它們。

同樣,我們作為 @nestjs/microservices 包的一部分提供的一些傳輸策略(包括 Kafka、gRPC 或 RabbitMQ)需要在建立連接之前訂閱/收聽特定主題/通道。 一旦你的應(yīng)用開始收聽消息,框架將無法訂閱/收聽新主題。

最后,啟用了代碼優(yōu)先方法的 @nestjs/graphql 包會根據(jù)元數(shù)據(jù)自動即時生成 GraphQL 模式。 這意味著,它需要預(yù)先加載所有類。 否則,將無法創(chuàng)建適當(dāng)?shù)?、有效的模式?/p>

常見用例

最常見的情況是,當(dāng)你的 worker/cron 作業(yè)/lambda 和無服務(wù)器函數(shù)/webhook 必須根據(jù)輸入?yún)?shù)(路由路徑/日期/查詢參數(shù)等)觸發(fā)不同的服務(wù)(不同的邏輯)時,你會看到延遲加載的模塊。 另一方面,延遲加載模塊對于整體應(yīng)用可能沒有太大意義,因為啟動時間無關(guān)緊要。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號