SKILL.md
SKILL.mdBrowse 7 files
3,482 tokens
13,914 bytes
Token encoding: o200k_base
Snapshot 646e806
1---2name: nx-import3description: Import, merge, or combine repositories into an Nx workspace using nx import. USE WHEN the user asks to adopt Nx across repos, move projects into a monorepo, or bring code/history from another repository.4---5 6## Quick Start7 8- `nx import` brings code from a source repository or folder into the current workspace, preserving commit history.9- After nx `22.6.0`, `nx import` responds with .ndjson outputs and follow-up questions. For earlier versions, always run with `--no-interactive` and specify all flags directly.10- Run `nx import --help` for available options.11- Make sure the destination directory is empty before importing.12 EXAMPLE: target has `libs/utils` and `libs/models`; source has `libs/ui` and `libs/data-access` — you cannot import `libs/` into `libs/` directly. Import each source library individually.13 14Primary docs:15 16- https://nx.dev/docs/guides/adopting-nx/import-project17- https://nx.dev/docs/guides/adopting-nx/preserving-git-histories18 19Read the nx docs if you have the tools for it.20 21## Import Strategy22 23**Subdirectory-at-a-time** (`nx import <source> apps --source=apps`):24 25- **Recommended for monorepo sources** — files land at top level, no redundant config26- Caveats: multiple import commands (separate merge commits each); dest must not have conflicting directories; root configs (deps, plugins, targetDefaults) not imported27- **Directory conflicts**: Import into alternate-named dir (e.g. `imported-apps/`), then rename28 29**Whole repo** (`nx import <source> imported --source=.`):30 31- **Only for non-monorepo sources** (single-project repos)32- For monorepos, creates messy nested config (`imported/nx.json`, `imported/tsconfig.base.json`, etc.)33- If you must: keep imported `tsconfig.base.json` (projects extend it), prefix workspace globs and executor paths34 35### Directory Conventions36 37- **Always prefer the destination's existing conventions.** Source uses `libs/`but dest uses `packages/`? Import into `packages/` (`nx import <source> packages/foo --source=libs/foo`).38- If dest has no convention (empty workspace), ask the user.39 40### Application vs Library Detection41 42Before importing, identify whether the source is an **application** or a **library**:43 44- **Applications**: Deployable end products. Common indicators:45 - _Frontend_: `next.config.*`, `vite.config.*` with a build entry point, framework-specific app scaffolding (CRA, Angular CLI app, etc.)46 - _Backend (Node.js)_: Express/Fastify/NestJS server entrypoint, no `"exports"` field in `package.json`47 - _JVM_: Maven `pom.xml` with `<packaging>jar</packaging>` or `<packaging>war</packaging>` and a `main` class; Gradle `application` plugin or `mainClass` setting48 - _.NET_: `.csproj`/`.fsproj` with `<OutputType>Exe</OutputType>` or `<OutputType>WinExe</OutputType>`49 - _General_: Dockerfile, a runnable entrypoint, no public API surface intended for import by other projects50- **Libraries**: Reusable packages consumed by other projects. Common indicators: `"main"`/`"exports"` in `package.json`, Maven/Gradle packaging as a library jar, .NET `<OutputType>Library</OutputType>`, named exports intended for import by other packages.51 52**Destination directory rules**:53 54- Applications → `apps/<name>`. Check workspace globs (e.g. `pnpm-workspace.yaml`, `workspaces` in root `package.json`) for an existing `apps/*` entry.55 - If `apps/*` is **not** present, add it before importing: update the workspace glob config and commit (or stage) the change.56 - Example: `nx import <source> apps/my-app --source=packages/my-app`57- Libraries → follow the dest's existing convention (`packages/`, `libs/`, etc.).58 59## Common Issues60 61### pnpm Workspace Globs (Critical)62 63`nx import` adds the imported directory itself (e.g. `apps`) to `pnpm-workspace.yaml`, **NOT** glob patterns for packages within it. Cross-package imports will fail with `Cannot find module`.64 65**Fix**: Replace with proper globs from the source config (e.g. `apps/*`, `libs/shared/*`), then `pnpm install`.66 67### Root Dependencies and Config Not Imported (Critical)68 69`nx import` does **NOT** merge from the source's root:70 71- `dependencies`/`devDependencies` from `package.json`72- `targetDefaults` from `nx.json` (e.g. `"@nx/esbuild:esbuild": { "dependsOn": ["^build"] }` — critical for build ordering)73- `namedInputs` from `nx.json` (e.g. `production` exclusion patterns for test files)74- Plugin configurations from `nx.json`75 76**Fix**: Diff source and dest `package.json` + `nx.json`. Add missing deps, merge relevant `targetDefaults` and `namedInputs`.77 78### TypeScript Project References79 80After import, run `nx sync --yes`. If it reports nothing but typecheck still fails, `nx reset` first, then `nx sync --yes` again.81 82### Explicit Executor Path Fixups83 84Inferred targets (via Nx plugins) resolve config relative to project root — no changes needed. Explicit executor targets (e.g. `@nx/esbuild:esbuild`) have workspace-root-relative paths (`main`, `outputPath`, `tsConfig`, `assets`, `sourceRoot`) that must be prefixed with the import destination directory.85 86### Plugin Detection87 88- **Whole-repo import**: `nx import` detects and offers to install plugins. Accept them.89- **Subdirectory import**: Plugins NOT auto-detected. Manually add with `npx nx add @nx/PLUGIN`. Check `include`/`exclude` patterns — defaults won't match alternate directories (e.g. `apps-beta/`).90- Run `npx nx reset` after any plugin config changes.91 92### Redundant Root Files (Whole-Repo Only)93 94Whole-repo import brings ALL source root files into the dest subdirectory. Clean up:95 96- `pnpm-lock.yaml` — stale; dest has its own lockfile97- `pnpm-workspace.yaml` — source workspace config; conflicts with dest98- `node_modules/` — stale symlinks pointing to source filesystem99- `.gitignore` — redundant with dest root `.gitignore`100- `nx.json` — source Nx config; dest has its own101- `README.md` — optional; keep or remove102 103**Don't blindly delete** `tsconfig.base.json` — imported projects may extend it via relative paths.104 105### Root ESLint Config Missing (Subdirectory Import)106 107Subdirectory import doesn't bring the source's root `eslint.config.mjs`, but project configs reference `../../eslint.config.mjs`.108 109**Fix order**:110 1111. Install ESLint deps first: `pnpm add -wD eslint@^9 @nx/eslint-plugin typescript-eslint` (plus framework-specific plugins)1122. Create root `eslint.config.mjs` (copy from source or create with `@nx/eslint-plugin` base rules)1133. Then `npx nx add @nx/eslint` to register the plugin in `nx.json`114 115Install `typescript-eslint` explicitly — pnpm's strict hoisting won't auto-resolve this transitive dep of `@nx/eslint-plugin`.116 117### ESLint Version Pinning (Critical)118 119**Pin ESLint to v9** (`eslint@^9.0.0`). ESLint 10 breaks `@nx/eslint` and many plugins with cryptic errors like `Cannot read properties of undefined (reading 'version')`.120 121`@nx/eslint` may peer-depend on ESLint 8, causing the wrong version to resolve. If lint fails with `Cannot read properties of undefined (reading 'allow')`, add `pnpm.overrides`:122 123```json124{ "pnpm": { "overrides": { "eslint": "^9.0.0" } } }125```126 127### Dependency Version Conflicts128 129After import, compare key deps (`typescript`, `eslint`, framework-specific). If dest uses newer versions, upgrade imported packages to match (usually safe). If source is newer, may need to upgrade dest first. Use `pnpm.overrides` to enforce single-version policy if desired.130 131### Module Boundaries132 133Imported projects may lack `tags`. Add tags or update `@nx/enforce-module-boundaries` rules.134 135### Project Name Collisions (Multi-Import)136 137Same `name` in `package.json` across source and dest causes `MultipleProjectsWithSameNameError`. **Fix**: Rename conflicting names (e.g. `@org/api` → `@org/teama-api`), update all dep references and import statements, `pnpm install`. The root `package.json` of each imported repo also becomes a project — rename those too.138 139### Workspace Dep Import Ordering140 141`pnpm install` fails during `nx import` if a `"workspace:*"` dependency hasn't been imported yet. File operations still succeed. **Fix**: Import all projects first, then `pnpm install --no-frozen-lockfile`.142 143### `.gitkeep` Blocking Subdirectory Import144 145The TS preset creates `packages/.gitkeep`. Remove it and commit before importing.146 147### Frontend tsconfig Base Settings (Critical)148 149The TS preset defaults (`module: "nodenext"`, `moduleResolution: "nodenext"`, `lib: ["es2022"]`) are incompatible with frontend frameworks (React, Next.js, Vue, Vite). After importing frontend projects, verify the dest root `tsconfig.base.json`:150 151- **`moduleResolution`**: Must be `"bundler"` (not `"nodenext"`)152- **`module`**: Must be `"esnext"` (not `"nodenext"`)153- **`lib`**: Must include `"dom"` and `"dom.iterable"` (frontend projects need these)154- **`jsx`**: `"react-jsx"` for React-only workspaces, per-project for mixed frameworks155 156For **subdirectory imports**, the dest root tsconfig is authoritative — update it. For **whole-repo imports**, imported projects may extend their own nested `tsconfig.base.json`, making this less critical.157 158If the dest also has backend projects needing `nodenext`, use per-project overrides instead of changing the root.159 160**Gotcha**: TypeScript does NOT merge `lib` arrays — a project-level override **replaces** the base array entirely. Always include all needed entries (e.g. `es2022`, `dom`, `dom.iterable`) in any project-level `lib`.161 162### `@nx/react` Typings for Libraries163 164React libraries generated with `@nx/react:library` reference `@nx/react/typings/cssmodule.d.ts` and `@nx/react/typings/image.d.ts` in their tsconfig `types`. These fail with `Cannot find type definition file` unless `@nx/react` is installed in the dest workspace.165 166**Fix**: `pnpm add -wD @nx/react`167 168### Jest Preset Missing (Subdirectory Import)169 170Nx presets create `jest.preset.js` at the workspace root, and project jest configs reference it (e.g. `../../jest.preset.js`). Subdirectory import does NOT bring this file.171 172**Fix**:173 1741. Run `npx nx add @nx/jest` — registers `@nx/jest/plugin` in `nx.json` and updates `namedInputs`1752. Create `jest.preset.js` at workspace root (see `references/JEST.md` for content) — `nx add` only creates this when a generator runs, not on bare `nx add`1763. Install test runner deps: `pnpm add -wD jest jest-environment-jsdom ts-jest @types/jest`1774. Install framework-specific test deps as needed (see `references/JEST.md`)178 179For deeper Jest issues (tsconfig.spec.json, Babel transforms, CI atomization, Jest vs Vitest coexistence), see `references/JEST.md`.180 181### Target Name Prefixing (Whole-Repo Import)182 183When importing a project with existing npm scripts (`build`, `dev`, `start`, `lint`), Nx plugins auto-prefix inferred target names to avoid conflicts: e.g. `next:build`, `vite:build`, `eslint:lint`.184 185**Fix**: Remove the Nx-rewritten npm scripts from the imported `package.json`, then either:186 187- Accept the prefixed names (e.g. `nx run app:next:build`)188- Rename plugin target names in `nx.json` to use unprefixed names189 190## Non-Nx Source Issues191 192When the source is a plain pnpm/npm workspace without `nx.json`.193 194### npm Script Rewriting (Critical)195 196Nx rewrites `package.json` scripts during init, creating broken commands (e.g. `vitest run` → `nx test run`). **Fix**: Remove all rewritten scripts — Nx plugins infer targets from config files.197 198### `noEmit` → `composite` + `emitDeclarationOnly` (Critical)199 200Plain TS projects use `"noEmit": true`, incompatible with Nx project references.201 202**Symptoms**: "typecheck target is disabled because one or more project references set 'noEmit: true'" or TS6310.203 204**Fix** in **all** imported tsconfigs:205 2061. Remove `"noEmit": true`. If inherited via extends chain, set `"noEmit": false` explicitly.2072. Add `"composite": true`, `"emitDeclarationOnly": true`, `"declarationMap": true`2083. Add `"outDir": "dist"` and `"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo"`2094. Add `"extends": "../../tsconfig.base.json"` if missing. Remove settings now inherited from base.210 211### Stale node_modules and Lockfiles212 213`nx import` may bring `node_modules/` (pnpm symlinks pointing to the source filesystem) and `pnpm-lock.yaml` from the source. Both are stale.214 215**Fix**: `rm -rf imported/node_modules imported/pnpm-lock.yaml imported/pnpm-workspace.yaml imported/.gitignore`, then `pnpm install`.216 217### ESLint Config Handling218 219- **Legacy `.eslintrc.json` (ESLint 8)**: Delete all `.eslintrc.*`, remove v8 deps, create flat `eslint.config.mjs`.220- **Flat config (`eslint.config.js`)**: Self-contained configs can often be left as-is.221- **No ESLint**: Create both root and project-level configs from scratch.222 223### TypeScript `paths` Aliases224 225Nx uses `package.json` `"exports"` + pnpm workspace linking instead of tsconfig `"paths"`. If packages have proper `"exports"`, paths are redundant. Otherwise, update paths for the new directory structure.226 227## Technology-specific Guidance228 229Identify technologies in the source repo, then read and apply the matching reference file(s).230 231Available references:232 233- `references/ESLINT.md` — ESLint projects: duplicate `lint`/`eslint:lint` targets, legacy `.eslintrc.*` linting generated files, flat config `.cjs` self-linting, `typescript-eslint` v7/v9 peer dep conflict, mixed ESLint v8+v9 in one workspace.234- `references/GRADLE.md`235- `references/JEST.md` — Jest testing: `@nx/jest/plugin` setup, jest.preset.js, testing deps by framework, tsconfig.spec.json, Jest vs Vitest coexistence, Babel transforms, CI atomization.236- `references/NEXT.md` — Next.js projects: `@nx/next/plugin` targets, `withNx`, Next.js TS config (`noEmit`, `jsx: "preserve"`), auto-installing deps via wrong PM, non-Nx `create-next-app` imports, mixed Next.js+Vite coexistence.237- `references/TURBOREPO.md`238- `references/VITE.md` — Vite projects (React, Vue, or both): `@nx/vite/plugin` typecheck target, `resolve.alias`/`__dirname` fixes, framework deps, Vue-specific setup, mixed React+Vue coexistence.239 Discovery context
Discovered by repository scan. No exact path reference found in the snapshot’s root AGENTS.md.