Tags: nrwl/nx
Tags
fix(testing)!: migrate @nx/jest to local dist build (#35713) ## Current Behavior `@nx/jest` builds into the shared `dist/packages/jest` directory at the workspace root and compiles with `commonjs` module resolution. It exposes no `exports` map, and first-party packages (`@nx/detox`, `@nx/node`) reach into `@nx/jest/src/*` for internal utilities. It also still re-exports the long-deprecated `jestProjectGenerator` alias. ## Expected Behavior `@nx/jest` builds locally into `packages/jest/dist/` with `nodenext` module resolution and an `exports` map, matching the already-migrated `nx`, `devkit`, and `js` packages. - `tsconfig.lib.json` / `tsconfig.spec.json` switched to the nodenext + local-`dist` pattern. - `package.json` gains an `exports` map (`.`, `./plugin`, `./preset`, `./plugins/resolver`, `./internal`, plus the JSON configs), `typesVersions`, and a `files` field. - `project.json` gains `release` (`preserveLocalDependencyProtocols`, `manifestRootsToUpdate`) and `nx-release-publish` configuration. - `executors.json` / `generators.json` / `migrations.json` factory and schema paths repointed to `./dist/src/...`. - `assets.json` outputs to the local `dist/` and copies `src/**/schema.json`. - `src/utils/versions.ts` resolves its own `package.json` via a `@nx/jest` self-reference instead of a `../../` relative path, which breaks once source compiles into `dist/`. - The `@nx/jest:jest` executor imports its `schema.json` statically rather than via a dynamic `await import`. - A curated `@nx/jest/internal` entry (mirroring `@nx/devkit/internal`) replaces deep `@nx/jest/src/*` imports for first-party consumers; `@nx/detox` and `@nx/node` are routed through it. - A migration (`rewrite-jest-internal-subpath-imports`) rewrites user `@nx/jest/src/*` imports: named imports/exports of public symbols go to `@nx/jest`, everything else to `@nx/jest/internal`. - A migration (`rewrite-jest-project-generator`) rewrites `jestProjectGenerator` imported from `@nx/jest` to `configurationGenerator`. The `dist-build-migration` skill is also updated to document the symbol-aware routing rule for the migration step. ### Breaking Changes - The deprecated `jestProjectGenerator` export is removed — its "removed in Nx v22" notice is two majors overdue. It was always just an alias for `configurationGenerator`; the `rewrite-jest-project-generator` migration rewrites existing usages automatically. ## Related Issue(s) Tracked by Linear NXC-3592 — `[M4] [Epic] Migrate @nx/jest to local dist`. No GitHub issue. <details> <summary>Pre-create review (run before PR open)</summary> ### Critical - The subpath-import migration originally rewrote every `@nx/jest/src/*` import to `@nx/jest/internal`, which would silently break consumers importing a public symbol (e.g. `findJestConfig`) that way. **Fixed** — the migration now partitions named imports/exports: public symbols route to `@nx/jest`, internals to `@nx/jest/internal`, splitting mixed declarations into two. ### Important - `export { ... } from '@nx/jest/src/*'` and additional `jest`/`vi` mock helpers were not handled by the initial migration. **Fixed** — export declarations are now partitioned like imports, and all eight mock-helper methods are covered with tests. ### Suggestions - `versions.ts` self-resolve and the inferred `build-base` target were flagged; both verified correct (matches the `@nx/js` pattern; `build-base` is inferred by `@nx/js/typescript` from `tsconfig.lib.json`). - Softened an over-broad "used only" comment in `eslint.config.mjs`. </details> --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
fix(core): restore nx/src/index entrypoint for Nx Cloud client compat… …ibility (#35712) ## Current Behavior Under Nx 23.0.0, the Nx Cloud agent client crashes when running tasks: ``` TypeError: runContinuousTasks is not a function at AgentTaskManager.invokeContinuousTasks at AgentTaskManager.reconcileContinuousTasks at AgentTaskManager.invokeTasks at executeTasksV3 ``` The Nx Cloud client probes the nx task APIs by `require`-ing `nx/src/index` (for the legacy `initTasksRunner`) and `nx/src/tasks-runner/init-tasks-runner` (for the modern `runDiscreteTasks` / `runContinuousTasks`) inside a single shared `try/catch`. PR #35708 removed the deprecated `initTasksRunner` API and **deleted `packages/nx/src/index.ts` entirely** — even though that PR's own commit message stated the file would be kept as an empty module so the `nx/src` subpath export mapping stays valid. With the file gone, `nx/src/index` no longer resolves (`./src/*` maps to `./dist/src/index.js`, which is never built). The `require('nx/src/index')` throws, the client's shared `catch` swallows it, and `runContinuousTasks` is never assigned — later crashing when invoked. `runContinuousTasks` itself was never removed; it still lives in `packages/nx/src/tasks-runner/init-tasks-runner.ts` and is unreachable here only because the earlier `nx/src/index` probe throws. ## Expected Behavior `packages/nx/src/index.ts` is restored as an empty ES module, so the `nx/src/index` entrypoint resolves again via the existing `./src/*` mapping in `package.json` exports (no `package.json` change needed). The deprecated `initTasksRunner` export stays removed — consumers still get `undefined` for it — but the `require` no longer throws, so the Nx Cloud client proceeds to load `runContinuousTasks` / `runDiscreteTasks` correctly. This restores compatibility for already-published/cached Nx Cloud client bundles without requiring them to be updated. ## Related Issue(s) Internal: NXC-4307 (follow-up to #35708) <!-- polygraph-session-start --> --- [View session information ↗](https://snapshot.app.trypolygraph.com/orgs/69cdc268b6aa527e4129c2b4/sessions/master-1efdcf12-fbbd-49c0-954c-3637c415400a-d8a02644) <!-- polygraph-session-end --> --------- Co-authored-by: Jason Jean <jasonjean1993@gmail.com> Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
fix(core): do not drop target defaults in 23.0.0 array migration (#35711 ) ## Current Behavior The `convert-target-defaults-to-array` migration (Nx 23) converts the legacy record-shape `targetDefaults` in `nx.json` to the new array shape. It declared a `projectGraph` parameter and classified each record key against the graph, dropping any key whose target name / executor wasn't found in the workspace. But the migration runner always invokes migrations as `fn(tree, {})` — the second argument is an empty object, never a project graph. `{}` is truthy, so it was treated as a real (but empty) graph. Every non-glob key then matched neither a target name nor an executor, and the migration dropped it. As a result, upgrading to Nx 23 deletes every named `targetDefaults` entry (`build`, `test`, `lint`, …) and keeps only glob entries — silently breaking `build` (lost `dependsOn`) and `test` (lost env/options) across the workspace. ## Expected Behavior The migration is a pure shape conversion and never drops entries: - The entry point takes an honest `(tree)` signature — it no longer pretends to receive a project graph it is never given. - Every legacy key produces at least one array entry. Globs and plain (non-`:`) keys become `{ target: key }`; `:` keys are disambiguated by the project graph (`target`, `executor`, or both), falling back to the syntactic heuristic (`:` → executor) when the graph has no signal. - The project graph is built internally, and only when a `:`-style key actually needs disambiguating. - The pure conversion is exposed as `convertTargetDefaultsRecordToArray` so the disambiguation logic is unit-testable with injected graphs, without standing up a workspace or the migration runner. ## Related Issue(s) N/A — caught while upgrading the Nx repo itself to `23.0.0-beta.13`.
fix(js): build to local dist and use nodenext (#35538) ## Current Behavior `@nx/js` builds to the shared workspace-root `dist/packages/js/` directory, uses CommonJS `module`/`moduleResolution`, has no `exports` map, and relies on `.npmignore`-style filtering through assets.json copies. This makes the package layout diverge from the new pattern already adopted by `nx` and `@nx/devkit`. ## Expected Behavior `@nx/js` follows the same local-dist build pattern as `nx` and `@nx/devkit`: - Builds to `packages/js/dist/` instead of `dist/packages/js/`. - `tsconfig.lib.json` uses `module`/`moduleResolution: "nodenext"` with `composite`, `rootDir: "."`, and `declarationDir: "dist"`. - `package.json` declares an `exports` map with the `@nx/nx-source` condition (workspace consumers resolve to `.ts` source, published consumers get built `.js`), plus a `./src/*` wildcard so the ~296 existing internal imports of `@nx/js/src/...` keep working. - `typesVersions` added for legacy `moduleResolution: "node"` consumers. - Adopts an explicit `files` field on `package.json` instead of asset-copying the root JSONs. - `generators.json`, `executors.json`, `migrations.json` factory/schema paths rewritten `./src/...` → `./dist/src/...` (matches `nx`). Workspace dev still works via the `tryResolveFromSource` fallback in `packages/nx/src/config/schema-utils.ts`. - `README.md` → `readme-template.md`; build command writes the rendered README to `packages/js/README.md`. Root `.gitignore` now ignores `packages/js/README.md` and `packages/js/**/*.d.ts` (with `!packages/js/src/**/schema.d.ts` exception for committed schema declarations). - ESLint flat config ignores `dist` and `**/*.d.ts`. - `project.json` adds `release.version` config (with `preserveLocalDependencyProtocols: false` so the not-yet-migrated `@nx/workspace` dep is substituted to a concrete version at version-time rather than left as `workspace:*` for pnpm publish to resolve from the un-bumped source `packages/workspace/package.json`) and `nx-release-publish.packageRoot`. The `build` target keeps its existing `dependsOn: ["build-base"]` (cannot use `^build` because js's `implicitDependencies` create a cycle through `eslint` / `eslint-plugin`). - `scripts/nx-release.ts`: adds `packages/js` to `packagesToReset` so the source `packages/js/package.json` is restored after release. ## Related Issue(s) Part of the ongoing migration of Nx packages to the local-dist build layout (following `nx` and `@nx/devkit`). --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
fix(misc): stop inferring `projects: 'self'` in `dependsOn` entries (#… …35686) ## Current Behavior The `@nx/cypress`, `@nx/jest`, `@nx/playwright` and `@nx/gradle` plugins infer atomized CI `dependsOn` entries that include `projects: 'self'`. That value is the default for `projects` and is no longer supported as an explicit value. ## Expected Behavior The plugins infer the same atomized CI `dependsOn` entries without setting `projects: 'self'`.
chore(core): refresh stale TUI snapshots on 22.7.x PR #35640 introduced these tests with snapshots that assumed PR #35540's Task::new helper, but #35540 is master-only. On 22.7.x the test setup still produces task1/task2/task3 ids (not app1:build etc.) and the selection arrow placement differs slightly. Regenerated the three affected snapshots to match current 22.7.x behavior; tests now pass cleanly.
chore(gradle): bump gradle project graph plugin version to 0.1.21 (#3… …5678) <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior The Gradle project graph plugin is at version 0.1.20. ## Expected Behavior The Gradle project graph plugin is bumped to version 0.1.21, with the corresponding migration files created so that users upgrading Nx will automatically get the new plugin version. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
chore(core)!: build @nx/workspace to local dist and use nodenext (#35643 ) ## Current Behavior `@nx/workspace` builds to the shared workspace-root `dist/packages/workspace/` directory, uses CommonJS `module`/`moduleResolution`, and has no `exports` map. Other Nx packages and external plugins reach into `@nx/workspace/src/*` subpaths for internal utilities. ## Expected Behavior `@nx/workspace` follows the same local-dist build pattern as `nx` and `@nx/devkit`: - Builds to `packages/workspace/dist/` instead of `dist/packages/workspace/`. - `tsconfig.lib.json` uses `module`/`moduleResolution: "nodenext"` with `composite`, `rootDir: "."`, `declarationDir: "dist"`. - `package.json` declares an `exports` map matching `@nx/devkit`'s locked-down surface — only named entry points, no `./src/*` wildcard. - `generators.json` / `executors.json` factory/schema paths rewritten `./src/...` → `./dist/src/...`. Workspace dev still works via the `tryResolveFromSource` fallback in `packages/nx/src/config/schema-utils.ts`. - `README.md` → `readme-template.md`; build command writes the rendered README to `packages/workspace/README.md`. - `project.json` adds `release.version` config (`preserveLocalDependencyProtocols: true`, matching nx/devkit). - `scripts/nx-release.ts`: adds `packages/workspace` to `packagesToReset`. Internal-leak cleanup so the locked-down exports map doesn't break first-party callers: - `TypeScriptCompilationOptions` + `compileTypeScript` moved from `@nx/workspace` to `@nx/js` (the package that owns TypeScript compilation). - `@nx/remix` inlines `directoryExists` (was a one-line re-export wrapper). - `@nx/rspack` drops the Nx 15.7-era `@nx/workspace/src/utils/create-ts-config` fallback. - e2e helpers source `angularDevkitVersion` from `@nx/angular/src/utils` instead. - `@nx/workspace` and `@nx/remix` no longer declare `@nx/workspace` deps they don't use. - Adds a preflight step to the `dist-build-migration` skill that warns about `workspace:*` deps on not-yet-migrated packages. ## Breaking Changes **`@nx/workspace/src/*` subpath imports are no longer supported.** The `exports` map no longer declares a `./src/*` wildcard. ~150 public consumers across GitHub use these subpaths today (the largest cluster is `src/utilities/fileutils` with ~60 hits). Migration: - `@nx/workspace/src/utilities/fileutils` (`directoryExists`, `fileExists`, `isRelativePath`, `createDirectory`) — these are thin re-exports from `nx/src/utils/fileutils`. Inline with `node:fs` (`statSync(p).isDirectory()` for `directoryExists`) or import from `@nx/devkit` where equivalent. - `@nx/workspace/src/utilities/typescript/compilation` — moved to `@nx/js`. Internal callers should import from there; if you were depending on the type externally, copy it or use the equivalent from `@nx/js`. - `@nx/workspace/src/utils/versions` — values are duplicated across packages; reimplement against the version of Nx you're targeting. - Other subpaths — check the `@nx/workspace`'s public `index.ts` re-exports first; otherwise reimplement. **`@nx/workspace/tasks-runners/default` now throws when invoked.** This module was an alias for `nx/src/tasks-runner/default-tasks-runner`. The Nx 17 (`use-minimal-config-for-tasks-runner-options`) and Nx 21 (`remove-custom-tasks-runner`) migrations rewrite/remove legacy `tasksRunnerOptions` entries. If your `nx.json` still references `@nx/workspace/tasks-runners/default`, replace it with `nx/tasks-runners/default`. ## Related Issue(s) Part of the ongoing migration of Nx packages to the local-dist build layout (following `nx` and `@nx/devkit`). --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
feat(misc)!: deprecate executors with inferred-plugin replacements (#… …35576) ## Current Behavior Most Nx executors that have an inferred-plugin alternative (`@nx/<pkg>/plugin`) and a `convert-to-inferred` generator are still wired up like first-class citizens. There is no signal — at scaffold time, schema browsing, or task execution — that they are on a path to removal, and the existing `cypress`/`detox` deprecation messages are inconsistent with the canonical pattern shipped most recently. ## Expected Behavior Every executor that has an inferred-plugin migration target is now deprecated through three surfaces, matching the canonical pattern: - **Runtime warning.** The executor logs that it is deprecated, will be removed in Nx v24, and points at `nx g @nx/<pkg>:convert-to-inferred`. - **Schema-root `x-deprecated`.** Surfaces in editor / Nx Console / `nx show project` views. - **Generation-time warning.** When a generator is about to scaffold a target that uses one of these executors because the corresponding inferred plugin isn't registered, it warns at generation time and points at the same migration path. All warnings link to <https://nx.dev/docs/guides/tasks--caching/convert-to-inferred>. ### Executors deprecated in this PR | Package | Executors | |---|---| | `@nx/webpack` | `webpack`, `dev-server` | | `@nx/vite` | `build`, `dev-server`, `preview-server` | | `@nx/rollup` | `rollup` | | `@nx/next` | `build`, `server` | | `@nx/remix` | `build`, `serve` | | `@nx/jest` | `jest` | | `@nx/playwright` | `playwright` | | `@nx/eslint` | `lint` | | `@nx/storybook` | `storybook`, `build` | | `@nx/rspack` | `rspack`, `dev-server` | | `@nx/expo` | `build`, `export`, `install`, `prebuild`, `run`, `serve`, `start`, `submit` | | `@nx/react-native` | `build-android`, `build-ios`, `bundle`, `pod-install`, `run-android`, `run-ios`, `start`, `upgrade` | | `@nx/vitest` | `test` | ### Generation-time warnings wired in - `@nx/<pkg>:configuration` for webpack, vite, rollup, jest, playwright, storybook, rspack, vitest - `@nx/<pkg>:application` for next, expo, react-native - `@nx/eslint:lint-project` legacy fallback path - `@nx/react:application` (webpack, rspack branches) and `@nx/react:library` (rollup legacy fallback) — warning text is inlined rather than imported. Two distinct reasons: - **rspack:** `@nx/react` does not declare a tsconfig project reference to `@nx/rspack`, so the deep import would not even type-check. - **webpack and rollup:** the project reference exists, so the deep import compiles, but `@nx/webpack` and `@nx/rollup` only expose `./index.js` in their package `exports` field. The import would resolve in source but throw `Cannot find module '@nx/<pkg>/src/utils/deprecation'` at runtime in published packages. - `@nx/react-native:web-configuration` (webpack) — inline for the same reason as the rspack case (no project reference). ### Scope notes - `@nx/vite:test` is intentionally **not** included — it is being removed entirely by PR #35517 (deprecation messaging would ship as dead code). `@nx/vitest:test` is now in scope: the `convert-to-inferred` generator for `@nx/vitest` is in place, so the deprecation has a real migration target. - `@nx/cypress`/`@nx/detox` already shipped earlier; this PR retitles their generation-time messages to the new wording (drop the redundant "register the plugin first" guidance, swap "Scaffolding" for "Generating") and points the detox URL at the general convert-to-inferred guide. - `@nx/react-native:storybook` is intentionally **not** included. The companion `@nx/react-native:storybook-configuration` generator was already removed in v21 and no generator has emitted this target since Jan 2024 (RN 0.73 upgrade). It will be removed outright in a follow-up PR rather than going through the deprecate-now / remove-in-v24 cycle. - `@nx/webpack:ssr-dev-server`, `@nx/expo:build-list`, `@nx/expo:sync-deps`, `@nx/expo:update`, `@nx/expo:ensure-symlink`, `@nx/react-native:sync-deps`, and `@nx/react-native:ensure-symlink` are intentionally left as-is — none are covered by `convert-to-inferred` and they have no clean replacement (Nx-specific glue or non-migrating utilities). - `@nx/esbuild:esbuild` and `@nx/nuxt:*` ship neither an inferred plugin nor a `convert-to-inferred` generator yet, so they're out of scope. - Per-package READMEs, introduction-doc banners, per-package "migration recipe" pages, and `migrations.json` entries are intentionally skipped per the canonical pattern (NXC-4422). The runtime warning carries the migration story. ## Related Issue(s) Fixes NXC-4423. Fixes NXC-4296. Fixes NXC-4294. Fixes NXC-4290. Fixes NXC-4285. Fixes NXC-4283. Fixes NXC-4286. Fixes NXC-4297. Fixes NXC-4293. Fixes NXC-4292. Fixes NXC-4282. Fixes NXC-4287. Fixes NXC-4295. Fixes NXC-4447. --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
chore(repo): provision build toolchain via mise in publish workflow (#… …35593) ## Current Behavior The `publish` workflow's matrix builds (Linux/macOS/Windows native binaries via N-API) install Java, Node.js, and pnpm manually inside each runner/container. With `@nx/dotnet` now in `nx.json`, these builds also need .NET to be available before the project graph can be loaded — and there's no .NET install on any of the matrix entries today, so the workflow fails at the `pnpm nx run-many --target=build-native` step. The macOS and `armv7-unknown-linux-gnueabihf` matrix entries already use `mise-action` and `mise.toml`, but the four Linux *docker* entries (Debian + Alpine, x64 + arm64) bypass mise entirely and provision tools through hand-rolled `apt-get` / `apk` / `nodesource` / `npm i -g pnpm` steps. ## Expected Behavior - All four Linux docker matrix entries now install `mise` from a signed/distro source (apt repo at `https://mise.jdx.dev/deb` for Debian, `apk add mise` from Alpine `community` for Alpine) and provision their entire toolchain — Node.js, Java, .NET, Maven, corepack — from `mise.toml`. This drops ~30 lines of bespoke install logic per entry and keeps versions in lockstep with the non-docker matrix entries, which already use `mise-action`. - Windows entries gain `choco install dotnet-9.0-sdk -y` alongside the existing OpenJDK install (mise's Windows .NET path is broken upstream — see [jdx/mise#4738](jdx/mise#4738)). - The FreeBSD build sets `NX_DOTNET_DISABLE=true` (added to both the `env:` block and the `cross-platform-actions/action` `environment_variables` allowlist so the var actually crosses into the FreeBSD VM) to opt out of the plugin entirely. - `NODE_VERSION` is now forwarded into `docker run` so containers honor the workflow's pinned Node version through `mise.toml`'s tera template instead of falling back to its `24.11.0` default. - `mise` itself is installed only via signed repositories — no `curl https://mise.run | sh` — so a hijacked DNS lookup against `mise.run` cannot drop a malicious script into our publish pipeline. ## Related Issue(s) N/A — workflow fix triggered by `@nx/dotnet` being added to `nx.json`.
PreviousNext