Closed2

NestJS v10 → v11

YOS0602YOS0602

Express v5

Express v5を使用するように変更。詳細はExpressのマイグレーションガイドを確認すると良い。

Migrating to Express 5

特筆すべき変更はpath文字列のマッチングアルゴリズム。

  • ワイルドカード(*)はnameを持つ必要がある
    • /* ではなく/*splat か /{*splat}を使用する
    • /*splatはroot以外の任意のpathにヒットするが、/{*splat} はrootも対象となる
  • オプショナルを意味する?はサポートされないため、中括弧を代わりに使用する: /:file{.:ext}
  • 正規表現はサポートされなくなった
  • (()[]?+!) を使う際には \ を使用してエスケープする
  • パラメータ名はJavaScriptの構文を使用できる
    • 避ける場合はクォートで囲む :"this”
  • middlewareでもワイルドカード(*)はnameを持つ必要がある forRoutes('{*splat}');

クエリパラメータのパース

Express v5ではクエリパラメータをparseするライブラリが変更されており、ネストしたobjectやarrayをサポートしていない。
v4と同じ挙動にするためには、 extended parserを使用するように設定する。

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule); // <-- Make sure to use <NestExpressApplication>
  app.set('query parser', 'extended'); // <-- Add this line
  await app.listen(3000);
}

Fastify v5

使ってないのでskip

Module resolution algorithm

パフォーマンス向上とメモ使用量削減のために、モジュール解決アルゴリズムが改善された。

ほとんどの場合、何かを変更する必要はないが、 Dynamic modules の使われ方によっては以前のバージョンと比べて挙動が変わる可能性がある。

v10以前では、複数のModulesでimportされたdynamic modulesは、NestJSによって動的メタデータからユニークなkeyが生成され、重複排除されるようになっていた。

v11からは、メタデータを使用したハッシュ値ではなく、オブジェクト参照が重複排除に使用される。複数のModulesで dynamic modules を共有したい場合、変数にアサインして必要なModulesからimportすれば良い。この新しいアプローチにより柔軟性が向上し、効率的にdynami modulesを扱える。

そこかしこで TypeOrmModule.forFeature([User])するのではなく、変数に代入しておいて参照を使いまわせということらしい。

export const typeOrmUser = TypeOrmModule.forFeature([User]);

Reflector type inference

Reflectorクラスにいくつかの変更点。機能性とメタデータの型推論が向上した。

  • getAllAndMerge
    • metadataが1つしかない場合、arrayではなくobjectがリターンされるようになった
  • getAllAndOverride
    • 戻り値の型が T からT | undefined に変更された
  • ReflectableDecoratorの型引数が正しく推論されるようになった

Lifecycle hooks execution order

Terminationライフサイクルhooks(OnModuleDestroyBeforeApplicationShutdown,  OnApplicationShutdown)の実行順序が変更された。initialized時のライフサイクルhooksとは逆に動く。

// A, B, C は全てmodulesで、"->" は依存方向を表す。
A -> B -> C

// OnModuleInit はこの順序で実行される。
C -> B -> A

// 一方で、OnModuleDestroy はこの順序となる。
A -> B -> C

Globalなmodulesは、initializedが最初に、destroyedが最後に実行される。

Cache module

@nestjs/cache-manager パッケージのCacheModule が、最新バージョンのcache-managerをサポートするよう更新された。

外部ストアの設定方法が変更されている。

// Old version - no longer supported
CacheModule.registerAsync({
  useFactory: async () => {
    const store = await redisStore({
      socket: {
        host: 'localhost',
        port: 6379,
      },
    });

    return {
      store,
    };
  },
}),

// New version - supported
CacheModule.registerAsync({
  useFactory: async () => {
    return {
      stores: [
        new KeyvRedis('redis://localhost:6379'),
      ],
    };
  },
}),

Config module

@nestjs/config@4.0.0にて、ConfigModule に破壊的変更が導入されたので注意。

ConfigService#getメソッドで読み込まれる値の優先順位が以下に変更された。

  1. 内部的なconfiguration(config namespace や カスタムconfigファイルでの指定)
  2. (バリデーションが有効化され、schemaが提供されているなら)Validateされた環境変数
  3. process.env オブジェクト

以前は2および3が、1より優先されていた。

他にも以下の変更がある。

  • ignoreEnvVars optionがdeprecateされた
    • 代わりにvalidatePredefined を使用する(事前定義された環境変数のバリデーションを無効化するにはfalseを設定する)
  • skipProcessEnv optionが導入された
    • trueに設定すると、ConfigService#get メソッドがprocess.env オブジェクトを読み込まなくなる

Node.jsバージョン

Node.js v20 以上が必要になった。

このスクラップは2025/01/20にクローズされました