🧹

Nest.jsにBiomeを導入する際にuseTypeImportの設定でハマった話

2024/05/01に公開

こんにちは!
近藤です!
今回は特定の事象に特化した話なのでさっくり書きます!

はじめに

Biomeが注目を集めていますね。私が関係する色々なプロジェクトでも導入が検討されています。
今回、Nest.jsのアプリケーションにBiomeを導入する際に、useImportTypeの設定でつまずいたので、その解決方法を共有します。

Biomeとは

BiomeはRustで書かれたコードフォーマッターで、eslintとprettierを組み合わせたようなツールです。Rustのエコシステムを活用しているため、高速で安定しています。元Romeのエンジニアによって開発され、デフォルトで多くの機能が含まれているため、特別な設定なしですぐに使い始めることができます。

Nest.jsについて

Nest.jsはNode.jsのフレームワークで、Express.jsをベースにAngularライクな構造を持っています。

問題の発生

Biomeをデフォルト設定のまま導入し、Nest.jsアプリケーションに適用しました。biome formatを実行した後、アプリケーションを起動すると、以下のよく見るエラーが発生しました。

Error: Nest can't resolve dependencies of the ${function name} (?). Please make sure that the argument Function at index [0] is available in the ${function name} context.

Potential solutions:
- Is ${function name} a valid NestJS module?
- If Function is a provider, is it part of the current ${function name}?
- If Function is exported from a separate @Module, is that module imported within ${function name}?
  @Module({ imports: [ /* the Module containing Function */ ] })

原因

このエラーが発生する主な原因は、Nest.jsが依存性注入を実装する方法に関連しています。[1]

Nest.jsの依存性注入

Nest.jsは、依存性注入を使用してモジュール化されたアプリケーション構造を実現します。このシステムはTypeScriptのデコレーターを使用しており、デコレーターはクラスやメソッドに対してメタデータを付与し、そのメタデータを使って依存関係を解決します。

TypeScriptのトランスパイル

TypeScriptがJavaScriptにトランスパイルされる際、型情報は削除されます。型のみのインポートは、型チェック後にインターフェースと同様に扱われ、結果として実行時のコードには存在しません。

実行時のエラー

Nest.jsの依存性注入はNode.jsの実行時に行われます。しかし、型のみのインポートにより、必要なメタデータがトランスパイルプロセス中に失われるため、依存関係を解決できずにエラーが発生します。

解決策

Biomeの設定を変更することで、この問題を解決できます。以下の手順を実行してください。

  1. フォーマッターを実行する前の状態に戻します。
  2. Biomeの設定ファイルで以下のようにuseImportTypeルールを無効化します。[2]
"lint": {
  "rules": {
    "useImportType": "off"
  }
}
  1. 再度フォーマッターを実行します。

これで、Nest.jsアプリケーションとBiomeを問題なく使用できるようになります。
ただ、全体でルールが適用されてしまうので、本来使いたい場所で使うことができなくなります。
type importはコンパイル時には無視されるため、バンドルサイズを小さくすることができるので有効な手段なのですが、上記の方法ではその恩恵を受けることができません。
あくまでもひとつの解決法として考えていただければと思います。

まとめ

Biomeを導入する際、useImportTypeの設定によってNest.jsアプリケーションでエラーが発生する可能性があります。この問題は、Biomeの設定を変更することで簡単に解決できます。Nest.jsとBiomeを組み合わせて使用する際は、この点に注意が必要です。

脚注
  1. Issue: Nest dependency injection can't resolve type-only imports ↩︎

  2. useImportType (since v1.5.0) ↩︎

コミューン株式会社

Discussion