fix(devkit): only rewrite deep-import paths in real import sites#35566
Conversation
The 23.0.0-beta.6 deep-import migration used a regex sweep to handle
non-named-import shapes (default / namespace / side-effect / require /
dynamic import / jest.mock-style calls). The sweep was too aggressive
and rewrote any `'@nx/devkit/src/...'` literal it found, including:
- Test fixtures inside template literals (mangled the migration's own
spec file as well as several plugin specs in nrwl/nx and downstream
repos).
- `typeof import('@nx/devkit/src/...')` type queries.
- Deep-import paths mentioned in comments.
- String-literal arguments to unrelated functions.
Replace the regex pass with a TypeScript-AST visitor that only rewrites
string-literal arguments to call expressions whose callee is `require`,
the dynamic-`import` keyword, or one of the `jest.*` / `vi.*` mock
helpers (`mock`, `unmock`, `doMock`, `dontMock`, `requireActual`,
`requireMock`, `importActual`, `importMock`). Type queries, template
literals, and comments are all naturally untouched because they aren't
`CallExpression` nodes. Quote style is preserved per literal.
Adds 10 new unit tests covering the previously-mangled cases and the
mock-helper rewrites.
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
View your CI Pipeline Execution ↗ for commit 59d3f7f
☁️ Nx Cloud last updated this comment at |
The `tools/workspace-plugin` repo generator was last meaningfully touched well before the strict `@nx/devkit` exports map landed and the templates it scaffolds rely on a deep import (\`@nx/devkit/src/utils/replace-project-configuration-with-plugin\`) pointing at a function that is not re-exported from any current devkit entry point. Anything generated from this template would fail to compile under 23.0.0-beta.6, so removing the generator outright rather than expanding the semi-private surface to keep it alive. Drops: - \`tools/workspace-plugin/src/generators/create-nodes-plugin/\` (full directory) - The \`create-nodes-plugin\` entry from \`tools/workspace-plugin/generators.json\` - The \"Creating a New Plugin\" example in \`.claude/skills/run-nx-generator/SKILL.md\`
There was a problem hiding this comment.
✅ The fix from Nx Cloud was applied
We removed the stale @nx/plugin dependency from tools/workspace-plugin/package.json to fix the workspace-plugin:lint failure. The create-nodes-plugin generator — the sole consumer of @nx/plugin — was deleted by this PR, leaving the dependency declared but unused and causing the @nx/dependency-checks ESLint rule to error.
Tip
✅ We verified this fix by re-running workspace-plugin:lint, e2e-eslint:e2e-ci--src/linter-legacy.test.ts.
Suggested Fix changes
diff --git a/tools/workspace-plugin/package.json b/tools/workspace-plugin/package.json
index 001cba59..ada4e553 100644
--- a/tools/workspace-plugin/package.json
+++ b/tools/workspace-plugin/package.json
@@ -8,7 +8,6 @@
"@nx/conformance": "5.0.4",
"@nx/devkit": "23.0.0-beta.4",
"@nx/js": "23.0.0-beta.4",
- "@nx/plugin": "23.0.0-beta.4",
"@xmldom/xmldom": "^0.8.10",
"glob": "7.1.4",
"semver": "catalog:",
🎓 Learn more about Self-Healing CI on nx.dev
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
|
This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request. |
Current Behavior
The 23.0.0-beta.6
@nx/devkitdeep-import migration (#35541) catches non-named-import shapes (default / namespace / side-effect /require()/ dynamicimport()/jest.mock-style calls) by running a regex sweep over the file:That sweep matches any
'@nx/devkit/src/...'literal anywhere in the file, regardless of context. As a result the migration mangled:update-deep-imports.spec.ts. Examples observed in the wild:packages/devkit/src/migrations/update-23-0-0/update-deep-imports.spec.ts,packages/expo/src/utils/expo-project-detection.spec.ts,packages/nuxt/src/plugins/plugin.spec.ts,packages/react-native/src/utils/react-native-project-detection.spec.ts, etc. (nrwl/nx#35565)typeof import('@nx/devkit/src/...')type queries — e.g.libs/shared/npm/src/lib/local-nx-utils/parse-target-string.tsin nrwl/nx-console, where the type now claims@nx/devkit/internalwhile the runtimeimportPathnext to it is built dynamically and still points atsrc/.... (nrwl/nx-console#3131)Expected Behavior
The migration only rewrites deep-import paths that are actually import sites. Everything else (template strings, type queries, comments, unrelated calls) is left alone.
This is implemented by replacing the regex sweep with a TypeScript-AST visitor that only rewrites the string-literal argument of
CallExpressionnodes whose callee is one of:require(identifier)importkeywordjest.mock/jest.unmock/jest.doMock/jest.dontMock/jest.requireActual/jest.requireMockvi.mock/vi.unmock/vi.doMock/vi.dontMock/vi.requireActual/vi.requireMock/vi.importActual/vi.importMockType queries (
ImportTypeNode), template literals, and comments are all naturally untouched because they are notCallExpressionnodes — no allowlist needed. Quote style is preserved per literal.The named-import bucketing pass and the duplicate-collapse pass are unchanged.
Tests
10 new unit tests:
non-runtime string literalsblock guarding template literals,typeof import(...)type queries, block comments, line comments, and unrelated call expressions.mock helper callsblock coveringjest.mock,jest.requireActual,vi.mock,vi.importActual, and a pairedimport+jest.mock+jest.requireActualcombination.All 39 unit tests pass;
nx build devkitis clean.Related Issue(s)
Follow-up to #35541. Workspaces that have already merged the bad rewrites need to revert those files by hand — there's no general way to undo the over-rewrites without losing the legitimate ones.