nx-import について
Git 履歴を保持してリポジトリやフォルダーを Nx ワークスペースへ取り込むためのガイダンススキルです。インポート方法の選択や、その後の設定上の問題への対処を支援します。
主な機能
- 01Git 履歴を保持したコードのインポート
- 02リポジトリ全体またはサブディレクトリの選択
- 03アプリケーションとライブラリの判別
- 04ワークスペースの glob と依存関係の設定
- 05TypeScript とプラグイン設定の問題への対処
活用シーン
- 01別リポジトリのプロジェクトを Nx に追加
- 02monorepo から選んだパッケージを取り込み
- 03ワークスペースのパッケージ解決エラーの調査
- 04取り込んだ TypeScript プロジェクトを Nx 向けに設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nrwl/ nx-ai-agents-config --skill nx-importインストール後、Claude Code で/nx-importを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/ESLINT.mdGRADLE.mdJEST.mdNEXT.mdTURBOREPO.mdVITE.md詳細
クイックスタート
nx import は、コードリポジトリまたはフォルダーから現在のワークスペースにコードを取り込み、コミット履歴を保持します。
- nx
22.6.0以降では、nx importは .ndjson 出力と追加の質問で応答します。それ以前のバージョンでは、--no-interactiveを付けて実行し、すべてのフラグを直接指定してください。 - 利用可能なオプションについては、
nx import --helpを実行してください。 - インポートする前に、インポート先が空であることを確認してください。
例: インポート先に
libs/utilsとlibs/modelsがあり、インポート元にlibs/uiとlibs/data-accessがある場合、libs/をlibs/に直接インポートすることはできません。インポート元のライブラリを個別にインポートしてください。
関連ドキュメント:
- https://nx.dev/docs/guides/adopting-nx/import-project
- https://nx.dev/docs/guides/adopting-nx/preserving-git-histories
必要なツールがある場合は、nx のドキュメントをお読みください。
インポート戦略
サブディレクトリ単位 (nx import <source> apps --source=apps):
- モノレポのインポート元に推奨 — ファイルはトップレベルに配置され、冗長な設定はありません
- 注意点: 複数のインポートコマンド(それぞれ別のマージコミット)が必要、インポート先に競合するディレクトリがあってはならない、ルート設定(deps、plugins、targetDefaults)はインポートされない
- ディレクトリの競合: 別名のディレクトリ(例:
imported-apps/)にインポートしてから、名前を変更します
リポジトリ全体 (nx import <source> imported --source=.):
- 非モノレポのインポート元のみ(単一プロジェクトのリポジトリ)
- モノレポの場合は、乱雑なネストされた設定(
imported/nx.json、imported/tsconfig.base.jsonなど)が作成されます - どうしても必要な場合: インポートされた
tsconfig.base.jsonを維持し(プロジェクトがこれを継承します)、ワークスペースの glob と executor のパスにプレフィックスを付けます
ディレクトリの規約
- 常にインポート先の既存の規約を優先してください。 インポート元が
libs/を使用し、インポート先がpackages/を使用している場合は、packages/にインポートします (nx import <source> packages/foo --source=libs/foo)。 - インポート先に規約がない場合(空のワークスペース)、ユーザーに確認してください。
アプリケーションとライブラリの判別
インポートする前に、インポート元がアプリケーションかライブラリかを判別します:
- アプリケーション: デプロイ可能な最終製品。一般的な指標:
- フロントエンド:
next.config.*、ビルドエントリポイントを持つvite.config.*、フレームワーク固有のアプリのスキャフォールディング(CRA、Angular CLI アプリなど) - バックエンド (Node.js): Express/Fastify/NestJS のサーバーエントリポイント、
package.jsonに"exports"フィールドがない - JVM:
<packaging>jar</packaging>または<packaging>war</packaging>とmainクラスを持つ Maven のpom.xml、Gradle のapplicationプラグインまたはmainClass設定 - .NET:
<OutputType>Exe</OutputType>または<OutputType>WinExe</OutputType>を持つ.csproj/.fsproj - 全般: Dockerfile、実行可能なエントリポイント、他のプロジェクトによるインポートを意図した公開 API サーフェスがない
- フロントエンド:
- ライブラリ: 他のプロジェクトによって利用される再利用可能なパッケージ。一般的な指標:
package.jsonの"main"/"exports"、ライブラリ jar としての Maven/Gradle パッケージング、.NET の<OutputType>Library</OutputType>、他のパッケージによるインポートを意図した名前付きエクスポート。
インポート先ディレクトリのルール:
- アプリケーション →
apps/<name>。既存のapps/*エントリがないか、ワークスペースの glob(例:pnpm-workspace.yaml、ルートpackage.jsonのworkspaces)を確認します。apps/*が存在しない場合は、インポートする前に追加します: ワークスペースの glob 設定を更新し、変更をコミット(またはステージ)します。- 例:
nx import <source> apps/my-app --source=packages/my-app
- ライブラリ → インポート先の既存の規約に従います(
packages/、libs/など)。
よくある問題
pnpm ワークスペースの glob (重要)
nx import は、インポートされたディレクトリ自体(例: apps)を pnpm-workspace.yaml に追加しますが、その中のパッケージの glob パターンは追加しません。パッケージ間のインポートは Cannot find module で失敗します。
修正: インポート元の設定から適切な glob(例: apps/*、libs/shared/*)に置き換え、pnpm install を実行します。
ルートの依存関係と設定がインポートされない (重大)
nx import はソースのルートからマージしません:
package.jsonのdependencies/devDependenciesnx.jsonのtargetDefaults(例:"@nx/esbuild:esbuild": { "dependsOn": ["^build"] }— ビルド順序に重要)nx.jsonのnamedInputs(例: テストファイルを除外するproductionパターン)nx.jsonのプラグイン設定
修正方法: ソースと移行先の package.json + nx.json を差分比較します。不足している依存関係を追加し、関連する targetDefaults と namedInputs をマージします。
TypeScript プロジェクト参照
インポート後に nx sync --yes を実行します。何も報告されないのに型チェックが依然として失敗する場合は、まず nx reset を実行し、その後再度 nx sync --yes を実行します。
明示的なエグゼキューターのパス修正
(Nx プラグイン経由の) 推論されたターゲットは、プロジェクトルートを基準に設定を解決します — 変更は不要です。明示的なエグゼキューターのターゲット (例: @nx/esbuild:esbuild) には、ワークスペースルートからの相対パス (main、outputPath、tsConfig、assets、sourceRoot) があり、インポート先ディレクトリをプレフィックスとして付ける必要があります。
プラグインの検出
- リポジトリ全体のインポート:
nx importはプラグインを検出し、インストールを提案します。それらを受け入れます。 - サブディレクトリのインポート: プラグインは自動検出されません。
npx nx add @nx/PLUGINで手動で追加します。include/excludeパターンを確認します — デフォルトでは別のディレクトリ (例:apps-beta/) に一致しません。 - プラグイン設定を変更した後は
npx nx resetを実行します。
冗長なルートファイル (リポジトリ全体のインポートのみ)
リポジトリ全体のインポートは、すべてのソースルートファイルを移行先のサブディレクトリに持ち込みます。クリーンアップします:
pnpm-lock.yaml— 古い; 移行先には独自のロックファイルがありますpnpm-workspace.yaml— ソースのワークスペース設定; 移行先と競合しますnode_modules/— ソースのファイルシステムを指す古いシンボリックリンク.gitignore— 移行先ルートの.gitignoreと重複nx.json— ソースの Nx 設定; 移行先には独自のものがありますREADME.md— 任意; 保持または削除
tsconfig.base.json を盲目的に削除しないでください — インポートされたプロジェクトが相対パス経由でそれを拡張している可能性があります。
ルートの ESLint 設定が欠落 (サブディレクトリのインポート)
サブディレクトリのインポートはソースのルート eslint.config.mjs を持ち込みませんが、プロジェクト設定は ../../eslint.config.mjs を参照します。
修正の順序:
- まず ESLint の依存関係をインストールします:
pnpm add -wD eslint@^9 @nx/eslint-plugin typescript-eslint(およびフレームワーク固有のプラグイン) - ルート
eslint.config.mjsを作成します (ソースからコピーするか、@nx/eslint-pluginの基本ルールで作成) - その後
npx nx add @nx/eslintを実行してnx.jsonにプラグインを登録します
typescript-eslint を明示的にインストールします — pnpm の厳格なホイスティングは @nx/eslint-plugin のこの推移的依存関係を自動解決しません。
ESLint のバージョン固定 (重大)
ESLint を v9 に固定します (eslint@^9.0.0)。ESLint 10 は @nx/eslint と多くのプラグインを Cannot read properties of undefined (reading 'version') のような不可解なエラーで壊します。
@nx/eslint は ESLint 8 にピア依存している可能性があり、誤ったバージョンが解決される原因になります。lint が Cannot read properties of undefined (reading 'allow') で失敗する場合は、pnpm.overrides を追加します:
{ "pnpm": { "overrides": { "eslint": "^9.0.0" } } }
依存関係のバージョン競合
インポート後に、主要な依存関係 (typescript、eslint、フレームワーク固有のもの) を比較します。移行先がより新しいバージョンを使用している場合は、インポートされたパッケージを一致するようにアップグレードします (通常は安全です)。ソースがより新しい場合は、まず移行先をアップグレードする必要があるかもしれません。必要に応じて、単一バージョンポリシーを強制するために pnpm.overrides を使用します。
モジュール境界
インポートされたプロジェクトには tags がない場合があります。タグを追加するか、@nx/enforce-module-boundaries ルールを更新します。
プロジェクト名の衝突 (複数インポート)
ソースと移行先で package.json の name が同じだと MultipleProjectsWithSameNameError が発生します。修正方法: 競合する名前を変更し (例: @org/api → @org/teama-api)、すべての依存参照と import 文を更新し、pnpm install を実行します。インポートされた各リポジトリのルート package.json もプロジェクトになるため、それらも名前を変更します。
ワークスペース依存関係のインポート順序
"workspace:*" 依存関係がまだインポートされていない場合、nx import 中に pnpm install が失敗します。ファイル操作は引き続き成功します。修正: まずすべてのプロジェクトをインポートし、その後 pnpm install --no-frozen-lockfile を実行します。
.gitkeep によるサブディレクトリのインポート阻害
TS プリセットは packages/.gitkeep を作成します。インポート前にこれを削除してコミットしてください。
フロントエンド向け tsconfig の基本設定 (重要)
TS プリセットのデフォルト (module: "nodenext"、moduleResolution: "nodenext"、lib: ["es2022"]) は、フロントエンドフレームワーク (React、Next.js、Vue、Vite) と互換性がありません。フロントエンドプロジェクトをインポートした後、インポート先ルートの tsconfig.base.json を確認してください:
moduleResolution:"bundler"である必要があります ("nodenext"ではなく)module:"esnext"である必要があります ("nodenext"ではなく)lib:"dom"と"dom.iterable"を含める必要があります (フロントエンドプロジェクトにはこれらが必要です)jsx: React のみのワークスペースでは"react-jsx"、混在フレームワークではプロジェクトごとに設定
サブディレクトリインポートの場合、インポート先ルートの tsconfig が権威となるため、それを更新してください。リポジトリ全体のインポートの場合、インポートされたプロジェクトが独自のネストされた tsconfig.base.json を継承する可能性があるため、これはそれほど重要ではありません。
インポート先に nodenext を必要とするバックエンドプロジェクトもある場合は、ルートを変更するのではなく、プロジェクトごとのオーバーライドを使用してください。
注意点: TypeScript は lib 配列をマージしません。プロジェクトレベルのオーバーライドはベースの配列を完全に置き換えます。プロジェクトレベルの lib には、常に必要なすべてのエントリ (例: es2022、dom、dom.iterable) を含めてください。
ライブラリ向け @nx/react の型定義
@nx/react:library で生成された React ライブラリは、tsconfig の types で @nx/react/typings/cssmodule.d.ts と @nx/react/typings/image.d.ts を参照します。インポート先のワークスペースに @nx/react がインストールされていない限り、これらは Cannot find type definition file で失敗します。
修正: pnpm add -wD @nx/react
Jest プリセットの欠落 (サブディレクトリインポート)
Nx プリセットはワークスペースルートに jest.preset.js を作成し、プロジェクトの jest 設定がそれを参照します (例: ../../jest.preset.js)。サブディレクトリインポートではこのファイルは持ち込まれません。
修正:
npx nx add @nx/jestを実行 —nx.jsonに@nx/jest/pluginを登録し、namedInputsを更新します- ワークスペースルートに
jest.preset.jsを作成 (内容はreferences/JEST.mdを参照) —nx addはジェネレーターの実行時にのみこれを作成し、単独のnx addでは作成しません - テストランナーの依存関係をインストール:
pnpm add -wD jest jest-environment-jsdom ts-jest @types/jest - 必要に応じてフレームワーク固有のテスト依存関係をインストール (
references/JEST.mdを参照)
より深い Jest の問題 (tsconfig.spec.json、Babel トランスフォーム、CI のアトミゼーション、Jest と Vitest の共存) については、references/JEST.md を参照してください。
ターゲット名のプレフィックス付け (リポジトリ全体のインポート)
既存の npm スクリプト (build、dev、start、lint) を持つプロジェクトをインポートすると、Nx プラグインは競合を避けるために推定ターゲット名に自動でプレフィックスを付けます (例: next:build、vite:build、eslint:lint)。
修正: インポートされた package.json から Nx によって書き換えられた npm スクリプトを削除し、次のいずれかを行います:
- プレフィックス付きの名前を受け入れる (例:
nx run app:next:build) nx.jsonでプラグインのターゲット名をプレフィックスなしの名前にリネームする
Nx 以外のソースの問題
ソースが nx.json を持たないプレーンな pnpm/npm ワークスペースの場合。
npm スクリプトの書き換え (重要)
Nx は初期化中に package.json スクリプトを書き換え、壊れたコマンドを作成します (例: vitest run → nx test run)。修正: 書き換えられたすべてのスクリプトを削除します — Nx プラグインは設定ファイルからターゲットを推定します。
noEmit → composite + emitDeclarationOnly (重要)
通常の TS プロジェクトでは "noEmit": true を使用しますが、これは Nx のプロジェクト参照と互換性がありません。
症状: 「typecheck target is disabled because one or more project references set 'noEmit: true'」または TS6310。
修正は、インポートされたすべての tsconfig で行います。
"noEmit": trueを削除します。extends チェーン経由で継承されている場合は、"noEmit": falseを明示的に設定します。"composite": true、"emitDeclarationOnly": true、"declarationMap": trueを追加します。"outDir": "dist"と"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo"を追加します。- 不足している場合は
"extends": "../../tsconfig.base.json"を追加します。base から継承されるようになった設定は削除します。
古い node_modules とロックファイル
nx import は、node_modules/ (ソースのファイルシステムを指す pnpm のシンボリックリンク) と pnpm-lock.yaml をソースから持ち込むことがあります。どちらも古い状態です。
修正: rm -rf imported/node_modules imported/pnpm-lock.yaml imported/pnpm-workspace.yaml imported/.gitignore を実行してから、pnpm install を実行します。
ESLint 設定の扱い
- レガシーな
.eslintrc.json(ESLint 8): すべての.eslintrc.*を削除し、v8 の依存関係を削除し、フラットなeslint.config.mjsを作成します。 - フラット設定 (
eslint.config.js): 自己完結型の設定は、多くの場合そのままにしておけます。 - ESLint なし: ルートとプロジェクトレベルの両方の設定をゼロから作成します。
TypeScript の paths エイリアス
Nx は、tsconfig の "paths" の代わりに package.json の "exports" + pnpm ワークスペースのリンクを使用します。パッケージに適切な "exports" があれば、paths は不要です。そうでない場合は、新しいディレクトリ構造に合わせて paths を更新します。
技術固有のガイダンス
ソースリポジトリ内の技術を特定し、一致する参照ファイルを読んで適用します。
利用可能な参照:
references/ESLINT.md— ESLint プロジェクト:lint/eslint:lintターゲットの重複、レガシーな.eslintrc.*による生成ファイルの lint、フラット設定.cjsの自己 lint、typescript-eslintv7/v9 の peer 依存関係の競合、1 つのワークスペース内での ESLint v8+v9 の混在。references/GRADLE.mdreferences/JEST.md— Jest テスト:@nx/jest/pluginのセットアップ、jest.preset.js、フレームワーク別のテスト依存関係、tsconfig.spec.json、Jest と Vitest の共存、Babel トランスフォーム、CI の細分化。references/NEXT.md— Next.js プロジェクト:@nx/next/pluginターゲット、withNx、Next.js の TS 設定 (noEmit、jsx: "preserve")、誤った PM による依存関係の自動インストール、非 Nx のcreate-next-appのインポート、Next.js+Vite の混在。references/TURBOREPO.mdreferences/VITE.md— Vite プロジェクト (React、Vue、またはその両方):@nx/vite/pluginの typecheck ターゲット、resolve.alias/__dirnameの修正、フレームワークの依存関係、Vue 固有のセットアップ、React+Vue の混在。