NestJS v10 → v11

↓Migration guide - FAQ | NestJS - A progressive Node.js framework
NestJS v11 が2025-01-16にリリースされた。
Expressを使用している自分が影響を受ける範囲を調べて、v10→v11にアップグレードして問題ないか確認する。

Express v5
Express v5を使用するように変更。詳細はExpressのマイグレーションガイドを確認すると良い。
特筆すべき変更は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(OnModuleDestroy
, BeforeApplicationShutdown
, 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
メソッドで読み込まれる値の優先順位が以下に変更された。
- 内部的なconfiguration(config namespace や カスタムconfigファイルでの指定)
- (バリデーションが有効化され、schemaが提供されているなら)Validateされた環境変数
-
process.env
オブジェクト
以前は2および3が、1より優先されていた。
他にも以下の変更がある。
-
ignoreEnvVars
optionがdeprecateされた- 代わりに
validatePredefined
を使用する(事前定義された環境変数のバリデーションを無効化するにはfalseを設定する)
- 代わりに
-
skipProcessEnv
optionが導入された- trueに設定すると、
ConfigService#get
メソッドがprocess.env
オブジェクトを読み込まなくなる
- trueに設定すると、
Node.jsバージョン
Node.js v20 以上が必要になった。