## Jest Jest-specific guidance for `nx import`. For the basic "Jest Preset Missing" fix (create `jest.preset.js`, install deps), see `SKILL.md`. This file covers deeper Jest integration issues. --- ### How `@nx/jest` Works `@nx/jest/plugin` scans for `jest.config.{ts,js,cjs,mjs,cts,mts}` and creates a `test` target for each project. **Plugin options:** ```json { "plugin": "@nx/jest/plugin", "options": { "targetName": "test" } } ``` `npx nx add @nx/jest` does two things: 1. **Registers `@nx/jest/plugin` in `nx.json`** — without this, no `test` targets are inferred 2. Updates `namedInputs.production` to exclude test files **Gotcha**: `nx add @nx/jest` does NOT create `jest.preset.js` — that file is only generated when you run a generator (e.g. `@nx/jest:configuration`). For imports, you must create it manually (see "Jest Preset" section below). **Other gotcha**: If you create `jest.preset.js` manually but skip `npx nx add @nx/jest`, the plugin won't be registered and `nx run PROJECT:test` will fail with "Cannot find target 'test'". You need both. --- ### Jest Preset The preset provides shared Jest configuration (test patterns, ts-jest transform, resolver, jsdom environment). **Root `jest.preset.js`:** ```js const nxPreset = require('@nx/jest/preset').default; module.exports = { ...nxPreset }; ``` **Project `jest.config.ts`:** ```ts export default { displayName: 'my-lib', preset: '../../jest.preset.js', // project-specific overrides }; ``` The `preset` path is relative from the project root to the workspace root. Subdirectory imports preserve the original relative path (e.g. `../../jest.preset.js`), which resolves correctly if the import destination matches the source directory depth. --- ### Testing Dependencies #### Core (always needed) ``` pnpm add -wD jest ts-jest @types/jest @nx/jest ``` #### Environment-specific - **DOM testing** (React, Vue, browser libs): `jest-environment-jsdom` - **Node testing** (APIs, CLIs): no extra deps (Jest defaults to `node` env, but Nx preset defaults to `jsdom`) #### React testing ``` pnpm add -wD @testing-library/react @testing-library/jest-dom ``` #### React with Babel (non-ts-jest transform) Some React projects use Babel instead of ts-jest for JSX transformation: ``` pnpm add -wD babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript ``` **When**: Project `jest.config` has `transform` using `babel-jest` instead of `ts-jest`. Common in older Nx workspaces and CRA migrations. #### Vue testing ``` pnpm add -wD @vue/test-utils ``` Vue projects typically use Vitest (not Jest) — see VITE.md. --- ### `tsconfig.spec.json` Jest projects need a `tsconfig.spec.json` that includes test files: ```json { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", "module": "commonjs", "types": ["jest", "node"] }, "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] } ``` **Common issues after import:** - Missing `"types": ["jest", "node"]` — causes `describe`/`it`/`expect` to be unrecognized - Missing `"module": "commonjs"` — Jest doesn't support ESM by default (ts-jest transpiles to CJS) - `include` array missing test patterns — TypeScript won't check test files --- ### Jest vs Vitest Coexistence Workspaces can have both: - **Jest**: Next.js apps, older React libs, Node libraries - **Vitest**: Vite-based React/Vue apps and libs Both `@nx/jest/plugin` and `@nx/vite/plugin` (which infers Vitest targets) coexist without conflicts — they detect different config files (`jest.config.*` vs `vite.config.*`). **Target naming**: Both default to `test`. If a project somehow has both config files, rename one: ```json { "plugin": "@nx/jest/plugin", "options": { "targetName": "jest-test" } } ``` --- ### `@testing-library/jest-dom` — Jest vs Vitest Projects migrating from Jest to Vitest (or workspaces with both) need different imports: **Jest** (in `test-setup.ts`): ```ts import '@testing-library/jest-dom'; ``` **Vitest** (in `test-setup.ts`): ```ts import '@testing-library/jest-dom/vitest'; ``` If the source used Jest but the dest workspace uses Vitest for that project type, update the import path. Also add `@testing-library/jest-dom` to tsconfig `types` array. --- ### Non-Nx Source: Test Script Rewriting Nx rewrites `package.json` scripts during init. Test scripts get broken: - `"test": "jest"` → `"test": "nx test"` (circular if no executor configured) - `"test": "vitest run"` → `"test": "nx test run"` (broken — `run` becomes an argument) **Fix**: Remove all rewritten test scripts. `@nx/jest/plugin` and `@nx/vite/plugin` infer test targets from config files. --- ### CI Atomization `@nx/jest/plugin` supports splitting tests per-file for CI parallelism: ```json { "plugin": "@nx/jest/plugin", "options": { "targetName": "test", "ciTargetName": "test-ci" } } ``` This creates `test-ci--src/lib/foo.spec.ts` targets for each test file, enabling Nx Cloud distribution. Not relevant during import, but useful for post-import CI setup. --- ### Common Post-Import Issues 1. **"Cannot find target 'test'"**: `@nx/jest/plugin` not registered in `nx.json`. Run `npx nx add @nx/jest` or manually add the plugin entry. 2. **"Cannot find module 'jest-preset'"**: `jest.preset.js` missing at workspace root. Create it (see SKILL.md). 3. **"Cannot find type definition file for 'jest'"**: Missing `@types/jest` or `tsconfig.spec.json` doesn't have `"types": ["jest", "node"]`. 4. **Tests fail with "Cannot use import statement outside a module"**: `ts-jest` not installed or not configured as transform. Check `jest.config.ts` transform section. 5. **Snapshot path mismatches**: After import, `__snapshots__` directories may have paths baked in. Run tests once with `--updateSnapshot` to regenerate. --- ## Fix Order ### Subdirectory Import (Nx Source) 1. `npx nx add @nx/jest` — registers plugin in `nx.json` (does NOT create `jest.preset.js`) 2. Create `jest.preset.js` manually (see "Jest Preset" section above) 3. Install deps: `pnpm add -wD jest jest-environment-jsdom ts-jest @types/jest` 4. Install framework test deps: `@testing-library/react @testing-library/jest-dom` (React), `@vue/test-utils` (Vue) 5. Verify `tsconfig.spec.json` has `"types": ["jest", "node"]` 6. `nx run-many -t test` ### Whole-Repo Import (Non-Nx Source) 1. Remove rewritten test scripts from `package.json` 2. `npx nx add @nx/jest` — registers plugin (does NOT create preset) 3. Create `jest.preset.js` manually 4. Install deps (same as above) 5. Verify/fix `jest.config.*` — ensure `preset` path points to root `jest.preset.js` 6. Verify/fix `tsconfig.spec.json` — add `types`, `module`, `include` if missing 7. `nx run-many -t test`