🔥

TypeScriptのエイリアス設定エラーの原因がtsconfig.node.jsonだった時の話

2024/11/27に公開

TypeScriptを使用して開発する時に合った事がないエラーが出たのでメモとして残します。


発生した問題

TypeScriptとVueを使ったプロジェクトで、以下のようなエラーが頻発しました。

Cannot find module '@/utils/helpers' or its corresponding type declarations.
Cannot find module '@/types/userTypes' or its corresponding type declarations.

さらに、TypeScriptのデバッグログを有効化すると、次のような情報が表示されていました。

DirectoryWatcher:: Triggered with /path/to/project/src/utils/helpers.ts :: WatchInfo: /path/to/project/src 1 undefined Config: /path/to/project/tsconfig.json WatchType: Failed Lookup Locations

「モジュールが見つからない」というエラーは、TypeScriptではよくある問題ですが、以下のような典型的な原因を調査しました。


試した解決方法

1. tsconfig.jsonの確認と修正

baseUrlpaths設定を間違えている可能性を疑い、以下のように確認しました。

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

問題なさそうですが、一応修正してもエラーは解決せず。


2. Viteのエイリアス設定を確認

次に、Viteのvite.config.tsをチェック。エイリアス設定が一致していないとエラーになる可能性があるためです。

import { defineConfig } from 'vite';

export default defineConfig({
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});

これも特に問題なし。とはいえ念のため修正してみましたが、状況は変わらず。


3. ファイルの存在を確認

モジュールが見つからないと言われるsrc/utils/helpers.tssrc/types/userTypes.tsが存在するかを確認しました。どちらのファイルも確かに存在しています。


4. TypeScriptのサーバーを再起動

エディタ(VSCode)のキャッシュが影響している可能性を疑い、TypeScriptサーバーを再起動しました。

  • コマンドパレット(Ctrl+Shift+P または Cmd+Shift+P)を開き、TypeScript: Restart TS Serverを実行。

これでもダメ。やはりエラーは消えません。


原因の発見: tsconfig.node.json

エラーが解決しないまま試行錯誤しているとき、ふとプロジェクト内にtsconfig.node.jsonというファイルが存在していることに気付きました。このファイルは、Node.js向けのTypeScript設定を独自に定義したものでした。

問題のtsconfig.node.json

{
  "compilerOptions": {
    "module": "CommonJS",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*"]
}

一見問題なさそうに見えますが、このファイルの存在によって、TypeScriptがモジュール解決でどちらのtsconfig.jsonを使用すべきか混乱していたのです。


解決方法: tsconfig.node.jsonを削除

問題のtsconfig.node.jsonを削除したところ、あっさりとエラーが解消しました。これにより、プロジェクト全体がtsconfig.jsonを基準に動作するようになり、モジュール解決の競合がなくなったのです。


なぜtsconfig.node.jsonが問題だったのか?

複数のtsconfig.jsonが存在する場合、TypeScriptはそれぞれのファイルを独立したプロジェクトとして扱います。そのため、特定のファイルがどのtsconfig.jsonに属するかを適切に判断できず、以下のような問題が発生します。

  1. モジュール解決の競合:

    • tsconfig.jsontsconfig.node.jsonpathsmoduleResolution設定が異なる場合、解決が失敗する。
  2. ディレクトリウォッチャーの混乱:

    • TypeScriptが同じディレクトリを異なる設定で監視しようとし、結果としてエラーが発生。

複数のtsconfig.jsonを使う場合の注意点

もし複数のtsconfig.jsonが必要な場合は、以下のように親子関係を明確にすることで問題を回避できます。

親子関係の例

親ファイル: tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "module": "ESNext"
  },
  "include": ["src/**/*"]
}

子ファイル: tsconfig.node.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "CommonJS"
  }
}

このように親子関係を明確にすれば、設定が統一され、競合を防ぐことができます。


まとめ

  • TypeScriptの「モジュールが見つからない」エラーは、複数のtsconfig.jsonが原因であることがあります。
  • 解決のためには、不要なtsconfig.jsonを削除するか、extendsを使って親子関係を明確にすることが有効です。

Discussion