😽

yarnでnode_modulesがあらわれず、typeの依存関係をvscodeが認識されなかった時の解決方法

2024/12/15に公開

問題

Yarnを使用したプロジェクトで、以下のような問題に直面することがあります:

  • VSCodeが型定義(Type Definitions)を認識しない

    • 例: import { useState } from 'react' の行で
      モジュール 'react' またはそれに対応する型宣言が見つかりません。
      
      と表示される。
  • node_modulesがプロジェクト内に存在しない

    • lsコマンドでnode_modulesを確認すると、フォルダ自体が見当たらない。

一見すると依存関係がインストールされていないように見えますが、実際にはYarnの設定が原因でnode_modulesが使用されていないケースがあります。

理由

この問題は、YarnのPlug'n'Play(PnP)モードが原因で発生していることが多いです。

Yarn v2以降(Berry)では、依存関係管理の仕組みが従来のnode_modules方式からPnP方式に変わりました。このPnP方式では、node_modulesフォルダを作成せず、依存関係を.pnp.cjsファイルで管理します。

  • PnPの仕組み:

    • 依存関係は.yarn/cacheに保存され、直接参照されます。
    • 物理的なnode_modulesフォルダが存在しないため、VSCodeや一部のツールが型定義を認識できなくなることがあります。
  • VSCodeが型定義を認識できない理由:

    • PnPモードに未対応のプラグインや拡張機能が、型情報の探索に失敗する。
    • tsconfig.json.yarnrc.ymlの設定がPnPモードを考慮していない。

解決方法

問題を解決するには、PnPモードを無効化してnode_modules方式に戻すか、PnPモードに適切に対応させる必要があります。

方法1: PnPモードを無効化(node_modulesを使用)

PnPモードを無効化し、従来のnode_modules方式に切り替えます。

  1. .yarnrc.ymlを編集
    プロジェクトルートにある.yarnrc.ymlを開き、以下を追加または修正します。

    nodeLinker: node-modules
    

    この設定により、Yarnがnode_modulesを使用するモードに切り替わります。

  2. キャッシュをクリアして再インストール
    以下のコマンドを実行します。

    rm -rf .pnp.cjs .pnp.loader.mjs node_modules
    yarn cache clean
    yarn install
    
  3. VSCodeを再起動
    設定変更後、VSCodeを再起動して型定義が正しく認識されるか確認します。

方法2: PnPモードを使用する

PnPモードを継続して使用したい場合は、VSCodeやプロジェクト設定をPnPに対応させる必要があります。

  1. VSCodeにPnP対応設定を追加
    プロジェクトルートに.vscode/settings.jsonを作成し、以下を記述します。

    {
      "typescript.tsdk": ".yarn/sdks/typescript",
      "eslint.nodePath": ".yarn/sdks"
    }
    

    これにより、VSCodeがYarnのPnP設定を利用するようになります。

  2. Yarn SDKをインストール
    以下のコマンドを実行して、YarnのSDKをセットアップします。

    yarn dlx @yarnpkg/sdks vscode
    

    これにより、PnPモードでのTypeScriptやESLintの動作が改善されます。

  3. 依存関係の型定義を確認
    型定義パッケージ(例: @types/react)がインストールされていない場合、以下を実行します。

    yarn add -D @types/react @types/react-dom
    
  4. VSCodeを再起動
    設定変更後、VSCodeを再起動します。

方法3: TypeScriptの設定を確認

PnPまたはnode_modules方式にかかわらず、tsconfig.jsonの設定を確認します。

  • compilerOptionsに以下が設定されていることを確認してください。

    {
      "compilerOptions": {
        "lib": ["dom", "dom.iterable", "esnext"],
        "jsx": "react-jsx",
        "moduleResolution": "node",
        "skipLibCheck": true
      }
    }
    
  • 特にmoduleResolutionnodeであることを確認します。

補足: PnPとNode Modulesの選択基準

特徴 Plug'n'Play(PnP) Node Modules
依存関係の保存場所 .pnp.cjs node_modules
インストール速度 高速 遅い
ディスク使用量 少ない 多い
ツール互換性 一部ツールで問題が発生する場合がある 高い
初心者向けの簡単さ 難しい(設定が必要) 簡単

PnPは速度や効率性に優れますが、互換性に問題がある場合はnode_modules方式を選択するのが安全です。

まとめ

  • PnPモードの理解と適切な設定が問題解決の鍵です。
  • ツールの互換性が気になる場合は、node_modules方式に切り替えるのが簡単な解決策です。
  • 設定変更後はVSCodeを再起動し、型定義が正しく認識されているか確認しましょう。

このガイドを参考に、プロジェクトに最適な依存関係管理方法を選択してください!

Discussion