From a64a7e2db937bca42369b7cbfa962c2421ade1f3 Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Wed, 1 May 2024 12:12:32 -0400 Subject: [PATCH] feat(core): cleanup for v19 (#22993) --- CODEOWNERS | 1 - docs/generated/devkit/README.md | 1 - docs/generated/devkit/TaskHasher.md | 8 +- docs/generated/devkit/Workspaces.md | 45 - docs/generated/manifests/menus.json | 17 - docs/generated/manifests/nx-api.json | 12 +- docs/generated/packages-metadata.json | 12 +- .../packages/devkit/documents/nx_devkit.md | 1 - .../packages/plugin/executors/e2e.json | 209 ---- docs/shared/reference/sitemap.md | 2 - nx-dev/nx-dev-e2e/src/packages.spec.ts | 1 - packages/cypress/migrations.json | 24 - .../update-cy-mount-usage.spec.ts.snap | 221 ---- .../update-15-0-0/add-cypress-inputs.spec.ts | 141 --- .../update-15-0-0/add-cypress-inputs.ts | 52 - .../update-cy-mount-usage.spec.ts | 338 ----- .../update-15-0-0/update-cy-mount-usage.ts | 197 --- .../__snapshots__/cypress-11.spec.ts.snap | 198 --- .../update-15-1-0/cypress-11.spec.ts | 344 ------ .../migrations/update-15-1-0/cypress-11.ts | 180 --- .../update-to-cypress-12.spec.ts.snap | 87 -- .../update-to-cypress-12.spec.ts | 717 ----------- .../update-15-5-0/update-to-cypress-12.ts | 245 ---- packages/detox/migrations.json | 36 - packages/devkit/.eslintrc.json | 12 +- packages/devkit/nx.ts | 15 - packages/devkit/package.json | 2 +- .../src/executors/parse-target-string.ts | 19 +- .../src/executors/read-target-options.ts | 55 +- .../generators/add-build-target-defaults.ts | 5 +- .../artifact-name-and-directory-utils.ts | 18 +- .../src/generators/executor-options-utils.ts | 12 +- .../devkit/src/generators/format-files.ts | 9 +- .../devkit/src/generators/generate-files.ts | 6 +- .../executor-to-plugin-migrator.ts | 30 +- .../generators/project-name-and-root-utils.ts | 11 +- .../src/generators/run-tasks-in-serial.ts | 2 +- packages/devkit/src/generators/to-js.ts | 2 +- .../src/generators/update-ts-configs-to-js.ts | 5 +- .../src/generators/visit-not-ignored-files.ts | 2 +- .../update-16-0-0-add-nx-packages.ts | 2 +- .../update-16-9-0/migrate-mf-util-usage.ts | 5 +- .../devkit/src/tasks/install-packages-task.ts | 14 +- packages/devkit/src/utils/add-plugin.ts | 25 +- .../utils/calculate-hash-for-create-nodes.ts | 6 +- packages/devkit/src/utils/config-utils.ts | 5 +- .../devkit/src/utils/convert-nx-executor.ts | 74 +- packages/devkit/src/utils/get-named-inputs.ts | 11 +- .../devkit/src/utils/get-workspace-layout.ts | 5 +- .../devkit/src/utils/invoke-nx-generator.ts | 22 +- .../src/utils/log-show-project-command.ts | 3 +- packages/devkit/src/utils/move-dir.ts | 5 +- packages/devkit/src/utils/package-json.ts | 24 +- packages/devkit/src/utils/replace-package.ts | 20 +- ...place-project-configuration-with-plugin.ts | 18 +- packages/esbuild/migrations.json | 15 - .../set-generate-package-json.spec.ts | 73 -- .../set-generate-package-json.ts | 32 - packages/eslint/migrations.json | 12 - .../update-15-0-0/add-eslint-inputs.spec.ts | 187 --- .../update-15-0-0/add-eslint-inputs.ts | 42 - .../update-15-7-1/add-eslint-ignore.spec.ts | 107 -- .../update-15-7-1/add-eslint-ignore.ts | 49 - packages/expo/migrations.json | 307 ----- .../add-new-expo-cli-targets.spec.ts | 45 - .../update-15-0-3/add-new-expo-cli-targets.ts | 68 - .../update-15-0-3/change-jest-preset.spec.ts | 124 -- .../update-15-0-3/change-jest-preset.ts | 90 -- .../change-webpack-to-metro.spec.ts | 56 - .../update-15-8-3/change-webpack-to-metro.ts | 39 - packages/jest/migrations.json | 64 - .../update-15-0-0/add-jest-inputs.spec.ts | 80 -- .../update-15-0-0/add-jest-inputs.ts | 46 - .../update-configs-jest-29.spec.ts.snap | 493 -------- .../update-tests-jest-29.spec.ts.snap | 199 --- .../update-configs-jest-29.spec.ts | 490 -------- .../update-15-8-0/update-configs-jest-29.ts | 230 ---- .../update-tests-jest-29.spec.ts | 182 --- .../update-15-8-0/update-tests-jest-29.ts | 96 -- packages/js/migrations.json | 18 - packages/js/package.json | 1 - .../update-15-8-0/rename-swcrc-config.spec.ts | 119 -- .../update-15-8-0/rename-swcrc-config.ts | 119 -- packages/next/migrations.json | 40 - .../build/lib/create-next-config-file.ts | 2 +- .../update-15-8-8/add-style-packages.spec.ts | 85 -- .../update-15-8-8/add-style-packages.ts | 35 - packages/nx/migrations.json | 24 - .../nx/src/command-line/release/changelog.ts | 2 +- .../command-line/release/command-object.ts | 2 +- packages/nx/src/command-line/report/report.ts | 3 +- ...spaces.spec.ts => to-project-name.spec.ts} | 2 +- packages/nx/src/config/to-project-name.ts | 10 + packages/nx/src/config/workspaces.ts | 38 - packages/nx/src/devkit-exports.ts | 6 - packages/nx/src/hasher/task-hasher.ts | 8 +- .../update-15-1-0/set-project-names.ts | 38 - .../migrations/update-15-8-2/update-nxw.ts | 6 - .../package-json-workspaces/create-nodes.ts | 2 +- .../project-json/build-nodes/project-json.ts | 2 +- packages/nx/src/project-graph/file-utils.ts | 9 +- .../nx/src/project-graph/plugins/loader.ts | 3 +- .../nx/src/project-graph/plugins/utils.ts | 2 +- .../nx/src/tasks-runner/create-task-graph.ts | 3 +- packages/nx/src/tasks-runner/run-command.ts | 9 +- packages/nx/src/utils/nx-plugin.deprecated.ts | 2 +- packages/nx/src/utils/typescript.ts | 3 - packages/plugin/executors.json | 10 - packages/plugin/migrations.json | 18 - packages/plugin/package.json | 2 - packages/plugin/src/executors/e2e/e2e.impl.ts | 79 -- packages/plugin/src/executors/e2e/schema.d.ts | 6 - packages/plugin/src/executors/e2e/schema.json | 220 ---- .../specify-output-capture.spec.ts | 88 -- .../update-15-0-0/specify-output-capture.ts | 61 - .../update-configs-jest-29.spec.ts.snap | 506 -------- .../update-tests-jest-29.spec.ts.snap | 187 --- .../update-15-9-0/jest-29-configs.ts | 231 ---- .../migrations/update-15-9-0/jest-29-tests.ts | 97 -- .../update-configs-jest-29.spec.ts | 491 -------- .../update-tests-jest-29.spec.ts | 183 --- .../update-16-2-0/replace-e2e-executor.ts | 7 +- packages/react-native/migrations.json | 287 ----- .../update-15-0-0/add-babel-inputs.spec.ts | 73 -- .../update-15-0-0/add-babel-inputs.ts | 7 - .../add-build-ios-target.spec.ts | 36 - .../update-15-9-1/add-build-ios-target.ts | 34 - packages/react/migrations.json | 160 --- ...nstall-webpack-rollup-dependencies.spec.ts | 62 - .../install-webpack-rollup-dependencies.ts | 42 - .../update-rollup-executor.spec.ts | 50 - .../update-15-3-0/update-rollup-executor.ts | 14 - .../webpack-config-setup.spec.ts.snap | 77 -- .../webpack-config-setup.spec.ts | 297 ----- .../update-15-6-3/webpack-config-setup.ts | 147 --- packages/rollup/migrations.json | 6 - .../update-15-0-0/add-babel-inputs.spec.ts | 73 -- .../update-15-0-0/add-babel-inputs.ts | 7 - packages/storybook/migrations.json | 111 -- .../add-storybook-inputs.spec.ts | 142 --- .../update-15-0-0/add-storybook-inputs.ts | 50 - .../refactor-executor-options.spec.ts.snap | 1093 ----------------- .../refactor-executor-options.spec.ts | 29 - .../refactor-executor-options.ts | 94 -- .../test-configs/various-projects.json | 828 ------------- .../ensure-webpack-package.spec.ts | 78 -- .../update-15-5-3/ensure-webpack-package.ts | 41 - .../add-addon-essentials-to-all.spec.ts.snap | 374 ------ .../add-addon-essentials-to-all.spec.ts | 300 ----- .../add-addon-essentials-to-all.ts | 374 ------ .../update-15-7-0/remove-root-config.ts | 312 ----- .../eslint-ignore-react-plugin.spec.ts | 2 +- .../test-configs/various-configs.json | 0 packages/vite/migrations.json | 64 - .../update-vite-tsconfig-paths.spec.ts | 33 - .../update-vite-tsconfig-paths.ts | 72 -- .../set-mode-in-configuration.spec.ts | 32 - .../set-mode-in-configuration.ts | 35 - .../update-report-directory.spec.ts | 148 --- .../update-15-4-3/update-report-directory.ts | 49 - packages/web/migrations.json | 24 - .../update-15-0-0/add-babel-inputs.spec.ts | 73 -- .../update-15-0-0/add-babel-inputs.ts | 7 - .../update-rollup-executor.spec.ts | 101 -- .../update-15-0-0/update-rollup-executor.ts | 42 - .../update-15-5-4/update-babel-preset.spec.ts | 62 - .../update-15-5-4/update-babel-preset.ts | 47 - .../add-dropped-dependencies.spec.ts | 115 -- .../update-15-9-1/add-dropped-dependencies.ts | 53 - packages/webpack/migrations.json | 24 - .../update-15-0-0/add-babel-inputs.spec.ts | 73 -- .../update-15-0-0/add-babel-inputs.ts | 7 - .../remove-es2015-polyfills-option.spec.ts | 67 - .../remove-es2015-polyfills-option.ts | 22 - .../webpack-config-setup.spec.ts.snap | 57 - .../webpack-config-setup.spec.ts | 287 ----- .../update-15-6-3/webpack-config-setup.ts | 143 --- .../add-babelUpwardRootMode-flag.spec.ts | 57 - .../add-babelUpwardRootMode-flag.ts | 32 - .../secondary-entry-points.ts | 10 +- packages/workspace/migrations.json | 18 - .../generate-workspace-files.spec.ts.snap | 160 --- .../workspace/src/generators/utils/presets.ts | 7 - ...t-configuration-into-project-json-files.ts | 9 - 184 files changed, 229 insertions(+), 16339 deletions(-) delete mode 100644 docs/generated/devkit/Workspaces.md delete mode 100644 docs/generated/packages/plugin/executors/e2e.json delete mode 100644 packages/cypress/src/migrations/update-15-0-0/__snapshots__/update-cy-mount-usage.spec.ts.snap delete mode 100644 packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.spec.ts delete mode 100644 packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.ts delete mode 100644 packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.spec.ts delete mode 100644 packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.ts delete mode 100644 packages/cypress/src/migrations/update-15-1-0/__snapshots__/cypress-11.spec.ts.snap delete mode 100644 packages/cypress/src/migrations/update-15-1-0/cypress-11.spec.ts delete mode 100644 packages/cypress/src/migrations/update-15-1-0/cypress-11.ts delete mode 100644 packages/cypress/src/migrations/update-15-5-0/__snapshots__/update-to-cypress-12.spec.ts.snap delete mode 100644 packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.spec.ts delete mode 100644 packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.ts delete mode 100644 packages/devkit/nx.ts delete mode 100644 packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.spec.ts delete mode 100644 packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.ts delete mode 100644 packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.spec.ts delete mode 100644 packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.ts delete mode 100644 packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.spec.ts delete mode 100644 packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.ts delete mode 100644 packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts delete mode 100644 packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts delete mode 100644 packages/expo/src/migrations/update-15-0-3/change-jest-preset.spec.ts delete mode 100644 packages/expo/src/migrations/update-15-0-3/change-jest-preset.ts delete mode 100644 packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.spec.ts delete mode 100644 packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.ts delete mode 100644 packages/jest/src/migrations/update-15-0-0/add-jest-inputs.spec.ts delete mode 100644 packages/jest/src/migrations/update-15-0-0/add-jest-inputs.ts delete mode 100644 packages/jest/src/migrations/update-15-8-0/__snapshots__/update-configs-jest-29.spec.ts.snap delete mode 100644 packages/jest/src/migrations/update-15-8-0/__snapshots__/update-tests-jest-29.spec.ts.snap delete mode 100644 packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.spec.ts delete mode 100644 packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.ts delete mode 100644 packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.spec.ts delete mode 100644 packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.ts delete mode 100644 packages/js/src/migrations/update-15-8-0/rename-swcrc-config.spec.ts delete mode 100644 packages/js/src/migrations/update-15-8-0/rename-swcrc-config.ts delete mode 100644 packages/next/src/migrations/update-15-8-8/add-style-packages.spec.ts delete mode 100644 packages/next/src/migrations/update-15-8-8/add-style-packages.ts rename packages/nx/src/config/{workspaces.spec.ts => to-project-name.spec.ts} (97%) create mode 100644 packages/nx/src/config/to-project-name.ts delete mode 100644 packages/nx/src/config/workspaces.ts delete mode 100644 packages/nx/src/migrations/update-15-1-0/set-project-names.ts delete mode 100644 packages/nx/src/migrations/update-15-8-2/update-nxw.ts delete mode 100644 packages/nx/src/utils/typescript.ts delete mode 100644 packages/plugin/executors.json delete mode 100644 packages/plugin/src/executors/e2e/e2e.impl.ts delete mode 100644 packages/plugin/src/executors/e2e/schema.d.ts delete mode 100644 packages/plugin/src/executors/e2e/schema.json delete mode 100644 packages/plugin/src/migrations/update-15-0-0/specify-output-capture.spec.ts delete mode 100644 packages/plugin/src/migrations/update-15-0-0/specify-output-capture.ts delete mode 100644 packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-configs-jest-29.spec.ts.snap delete mode 100644 packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-tests-jest-29.spec.ts.snap delete mode 100644 packages/plugin/src/migrations/update-15-9-0/jest-29-configs.ts delete mode 100644 packages/plugin/src/migrations/update-15-9-0/jest-29-tests.ts delete mode 100644 packages/plugin/src/migrations/update-15-9-0/update-configs-jest-29.spec.ts delete mode 100644 packages/plugin/src/migrations/update-15-9-0/update-tests-jest-29.spec.ts delete mode 100644 packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.spec.ts delete mode 100644 packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.ts delete mode 100644 packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.spec.ts delete mode 100644 packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.ts delete mode 100644 packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.spec.ts delete mode 100644 packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.ts delete mode 100644 packages/react/src/migrations/update-15-3-0/update-rollup-executor.spec.ts delete mode 100644 packages/react/src/migrations/update-15-3-0/update-rollup-executor.ts delete mode 100644 packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap delete mode 100644 packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts delete mode 100644 packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts delete mode 100644 packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.spec.ts delete mode 100644 packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.ts delete mode 100644 packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.spec.ts delete mode 100644 packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.ts delete mode 100644 packages/storybook/src/migrations/update-15-4-6/__snapshots__/refactor-executor-options.spec.ts.snap delete mode 100644 packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.spec.ts delete mode 100644 packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.ts delete mode 100644 packages/storybook/src/migrations/update-15-4-6/test-configs/various-projects.json delete mode 100644 packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.spec.ts delete mode 100644 packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.ts delete mode 100644 packages/storybook/src/migrations/update-15-7-0/__snapshots__/add-addon-essentials-to-all.spec.ts.snap delete mode 100644 packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.spec.ts delete mode 100644 packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.ts delete mode 100644 packages/storybook/src/migrations/update-15-7-0/remove-root-config.ts rename packages/storybook/src/migrations/{update-15-7-0 => update-16-1-0}/test-configs/various-configs.json (100%) delete mode 100644 packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.spec.ts delete mode 100644 packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.ts delete mode 100644 packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.spec.ts delete mode 100644 packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.ts delete mode 100644 packages/vite/src/migrations/update-15-4-3/update-report-directory.spec.ts delete mode 100644 packages/vite/src/migrations/update-15-4-3/update-report-directory.ts delete mode 100644 packages/web/src/migrations/update-15-0-0/add-babel-inputs.spec.ts delete mode 100644 packages/web/src/migrations/update-15-0-0/add-babel-inputs.ts delete mode 100644 packages/web/src/migrations/update-15-0-0/update-rollup-executor.spec.ts delete mode 100644 packages/web/src/migrations/update-15-0-0/update-rollup-executor.ts delete mode 100644 packages/web/src/migrations/update-15-5-4/update-babel-preset.spec.ts delete mode 100644 packages/web/src/migrations/update-15-5-4/update-babel-preset.ts delete mode 100644 packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.spec.ts delete mode 100644 packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.ts delete mode 100644 packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.spec.ts delete mode 100644 packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.ts delete mode 100644 packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.spec.ts delete mode 100644 packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.ts delete mode 100644 packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap delete mode 100644 packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts delete mode 100644 packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts delete mode 100644 packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.spec.ts delete mode 100644 packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.ts delete mode 100644 packages/workspace/src/migrations/update-15-7-0/split-configuration-into-project-json-files.ts diff --git a/CODEOWNERS b/CODEOWNERS index a9337f894fe7c..2d4069ca7b36a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -136,7 +136,6 @@ rust-toolchain @nrwl/nx-native-reviewers /packages/devkit/** @nrwl/nx-devkit-reviewers /packages/devkit/index.ts @FrozenPandaz @vsavkin /packages/devkit/public-api.ts @FrozenPandaz @vsavkin -/packages/devkit/nx.ts @FrozenPandaz @vsavkin # Gradle /packages/gradle/** @FrozenPandaz @xiongemi diff --git a/docs/generated/devkit/README.md b/docs/generated/devkit/README.md index 105ae4251b0a4..c2dc580fd2e2c 100644 --- a/docs/generated/devkit/README.md +++ b/docs/generated/devkit/README.md @@ -19,7 +19,6 @@ It only uses language primitives and immutable objects ### Classes - [ProjectGraphBuilder](../../devkit/documents/ProjectGraphBuilder) -- [Workspaces](../../devkit/documents/Workspaces) ### Interfaces diff --git a/docs/generated/devkit/TaskHasher.md b/docs/generated/devkit/TaskHasher.md index 3d928bc1b29a8..11b8324afaac6 100644 --- a/docs/generated/devkit/TaskHasher.md +++ b/docs/generated/devkit/TaskHasher.md @@ -25,7 +25,7 @@ **`Deprecated`** -use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 +use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 ▸ **hashTask**(`task`, `taskGraph`): `Promise`\<[`Hash`](../../devkit/documents/Hash)\> @@ -42,7 +42,7 @@ use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. T **`Deprecated`** -use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 +use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 ▸ **hashTask**(`task`, `taskGraph`, `env`): `Promise`\<[`Hash`](../../devkit/documents/Hash)\> @@ -76,7 +76,7 @@ use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. T **`Deprecated`** -use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 +use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 ▸ **hashTasks**(`tasks`, `taskGraph`): `Promise`\<[`Hash`](../../devkit/documents/Hash)[]\> @@ -93,7 +93,7 @@ use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instea **`Deprecated`** -use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 +use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 ▸ **hashTasks**(`tasks`, `taskGraph`, `env`): `Promise`\<[`Hash`](../../devkit/documents/Hash)[]\> diff --git a/docs/generated/devkit/Workspaces.md b/docs/generated/devkit/Workspaces.md deleted file mode 100644 index 949d923514db9..0000000000000 --- a/docs/generated/devkit/Workspaces.md +++ /dev/null @@ -1,45 +0,0 @@ -# Class: Workspaces - -**`Deprecated`** - -This will be removed in v19. Use [readProjectsConfigurationFromProjectGraph](../../devkit/documents/readProjectsConfigurationFromProjectGraph) instead. - -## Table of contents - -### Constructors - -- [constructor](../../devkit/documents/Workspaces#constructor) - -### Methods - -- [readWorkspaceConfiguration](../../devkit/documents/Workspaces#readworkspaceconfiguration) - -## Constructors - -### constructor - -• **new Workspaces**(`root`): [`Workspaces`](../../devkit/documents/Workspaces) - -#### Parameters - -| Name | Type | -| :----- | :------- | -| `root` | `string` | - -#### Returns - -[`Workspaces`](../../devkit/documents/Workspaces) - -## Methods - -### readWorkspaceConfiguration - -▸ **readWorkspaceConfiguration**(): [`ProjectsConfigurations`](../../devkit/documents/ProjectsConfigurations) & [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)\<`string`[] \| `"*"`\> - -#### Returns - -[`ProjectsConfigurations`](../../devkit/documents/ProjectsConfigurations) & [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)\<`string`[] \| `"*"`\> - -**`Deprecated`** - -Use [readProjectsConfigurationFromProjectGraph](../../devkit/documents/readProjectsConfigurationFromProjectGraph) instead. diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 06db5726f620e..efe9e90e68cbc 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -8630,23 +8630,6 @@ "isExternal": false, "disableCollapsible": false }, - { - "id": "executors", - "path": "/nx-api/plugin/executors", - "name": "executors", - "children": [ - { - "id": "e2e", - "path": "/nx-api/plugin/executors/e2e", - "name": "e2e", - "children": [], - "isExternal": false, - "disableCollapsible": false - } - ], - "isExternal": false, - "disableCollapsible": false - }, { "id": "generators", "path": "/nx-api/plugin/generators", diff --git a/docs/generated/manifests/nx-api.json b/docs/generated/manifests/nx-api.json index ce13570984cbc..7f55c2080c5b8 100644 --- a/docs/generated/manifests/nx-api.json +++ b/docs/generated/manifests/nx-api.json @@ -2072,17 +2072,7 @@ }, "root": "/packages/plugin", "source": "/packages/plugin/src", - "executors": { - "/nx-api/plugin/executors/e2e": { - "description": "Creates and runs the E2E tests for an Nx Plugin.", - "file": "generated/packages/plugin/executors/e2e.json", - "hidden": false, - "name": "e2e", - "originalFilePath": "/packages/plugin/src/executors/e2e/schema.json", - "path": "/nx-api/plugin/executors/e2e", - "type": "executor" - } - }, + "executors": {}, "generators": { "/nx-api/plugin/generators/plugin": { "description": "Create a Nx Plugin.", diff --git a/docs/generated/packages-metadata.json b/docs/generated/packages-metadata.json index 8e5cab6fd0947..912fe47c885ce 100644 --- a/docs/generated/packages-metadata.json +++ b/docs/generated/packages-metadata.json @@ -2047,17 +2047,7 @@ "originalFilePath": "shared/packages/plugin/plugin" } ], - "executors": [ - { - "description": "Creates and runs the E2E tests for an Nx Plugin.", - "file": "generated/packages/plugin/executors/e2e.json", - "hidden": false, - "name": "e2e", - "originalFilePath": "/packages/plugin/src/executors/e2e/schema.json", - "path": "plugin/executors/e2e", - "type": "executor" - } - ], + "executors": [], "generators": [ { "description": "Create a Nx Plugin.", diff --git a/docs/generated/packages/devkit/documents/nx_devkit.md b/docs/generated/packages/devkit/documents/nx_devkit.md index 105ae4251b0a4..c2dc580fd2e2c 100644 --- a/docs/generated/packages/devkit/documents/nx_devkit.md +++ b/docs/generated/packages/devkit/documents/nx_devkit.md @@ -19,7 +19,6 @@ It only uses language primitives and immutable objects ### Classes - [ProjectGraphBuilder](../../devkit/documents/ProjectGraphBuilder) -- [Workspaces](../../devkit/documents/Workspaces) ### Interfaces diff --git a/docs/generated/packages/plugin/executors/e2e.json b/docs/generated/packages/plugin/executors/e2e.json deleted file mode 100644 index e6c2f25dc2315..0000000000000 --- a/docs/generated/packages/plugin/executors/e2e.json +++ /dev/null @@ -1,209 +0,0 @@ -{ - "name": "e2e", - "implementation": "/packages/plugin/src/executors/e2e/e2e.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "title": "Nx Plugin Playground Target", - "description": "Creates a playground for a Nx Plugin.", - "cli": "nx", - "type": "object", - "properties": { - "target": { - "description": "The build target for the Nx Plugin project.", - "type": "string", - "x-priority": "important" - }, - "jestConfig": { - "type": "string", - "description": "Jest config file.", - "x-completion-type": "file", - "x-completion-glob": "jest.config@(.js|.ts)", - "x-priority": "important" - }, - "tsSpecConfig": { - "type": "string", - "description": "The tsconfig file for specs.", - "x-deprecated": "Use the `tsconfig` property for `ts-jest` in the e2e project `jest.config.js` file. It will be removed in the next major release.", - "x-completion-type": "file", - "x-completion-glob": "tsconfig.*.json", - "x-priority": "important" - }, - "codeCoverage": { - "description": "Indicates that test coverage information should be collected and reported in the output. (https://jestjs.io/docs/cli#--coverageboolean)", - "type": "boolean", - "aliases": ["coverage"] - }, - "config": { - "description": "The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.", - "type": "string" - }, - "clearCache": { - "description": "Deletes the Jest cache directory and then exits without running tests. Will delete Jest's default cache directory. _Note: clearing the cache will reduce performance_.", - "type": "boolean" - }, - "detectOpenHandles": { - "description": "Attempt to collect and print open handles preventing Jest from exiting cleanly (https://jestjs.io/docs/cli#--detectopenhandles)", - "type": "boolean" - }, - "logHeapUsage": { - "description": "Logs the heap usage after every test. Useful to debug memory leaks. Use together with --runInBand and --expose-gc in node.", - "type": "boolean" - }, - "detectLeaks": { - "description": "**EXPERIMENTAL**: Detect memory leaks in tests. After executing a test, it will try to garbage collect the global object used, and fail if it was leaked", - "type": "boolean" - }, - "testFile": { - "description": "The name of the file to test.", - "type": "string", - "x-completion-type": "file", - "x-completion-glob": "**/*.+(spec|test).+(ts|js)" - }, - "tsConfig": { - "description": "The name of the Typescript configuration file. Set the tsconfig option in the jest config file. ", - "type": "string", - "x-deprecated": "Use the ts-jest configuration options in the jest config file instead." - }, - "setupFile": { - "description": "The name of a setup file used by Jest. (use Jest config file https://jestjs.io/docs/en/configuration#setupfilesafterenv-array)", - "type": "string", - "x-deprecated": "Use the setupFilesAfterEnv option in the jest config file. https://jestjs.io/docs/en/configuration#setupfilesafterenv-array" - }, - "bail": { - "alias": "b", - "description": "Exit the test suite immediately after `n` number of failing tests. (https://jestjs.io/docs/cli#--bail)", - "oneOf": [{ "type": "number" }, { "type": "boolean" }] - }, - "ci": { - "description": "Whether to run Jest in continuous integration (CI) mode. This option is on by default in most popular CI environments. It will prevent snapshots from being written unless explicitly requested. (https://jestjs.io/docs/cli#--ci)", - "type": "boolean" - }, - "color": { - "alias": "colors", - "description": "Forces test results output color highlighting (even if `stdout` is not a TTY). Set to false if you would like to have no colors. (https://jestjs.io/docs/cli#--colors)", - "type": "boolean" - }, - "findRelatedTests": { - "description": "Find and run the tests that cover a comma separated list of source files that were passed in as arguments. (https://jestjs.io/docs/cli#--findrelatedtests-spaceseparatedlistofsourcefiles)", - "type": "string" - }, - "json": { - "description": "Prints the test results in `JSON`. This mode will send all other test output and user messages to `stderr`. (https://jestjs.io/docs/cli#--json)", - "type": "boolean" - }, - "maxWorkers": { - "alias": "w", - "description": "Specifies the maximum number of workers the worker-pool will spawn for running tests. This defaults to the number of the cores available on your machine. Useful for CI. (its usually best not to override this default) (https://jestjs.io/docs/cli#--maxworkersnumstring)", - "oneOf": [{ "type": "number" }, { "type": "string" }] - }, - "onlyChanged": { - "alias": "o", - "description": "Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a `git` or `hg` repository at the moment. (https://jestjs.io/docs/cli#--onlychanged)", - "type": "boolean" - }, - "changedSince": { - "description": "Runs tests related to the changes since the provided branch or commit hash. If the current branch has diverged from the given branch, then only changes made locally will be tested. (https://jestjs.io/docs/cli#--changedsince)", - "type": "string" - }, - "outputFile": { - "description": "Write test results to a file when the `--json` option is also specified. (https://jestjs.io/docs/cli#--outputfilefilename)", - "type": "string" - }, - "passWithNoTests": { - "description": "Will not fail if no tests are found (for example while using `--testPathPattern`.) (https://jestjs.io/docs/cli#--passwithnotests)", - "type": "boolean" - }, - "runInBand": { - "alias": "i", - "description": "Run all tests serially in the current process (rather than creating a worker pool of child processes that run tests). This is sometimes useful for debugging, but such use cases are pretty rare. Useful for CI. (https://jestjs.io/docs/cli#--runinband)", - "type": "boolean", - "default": true - }, - "showConfig": { - "description": "Print your Jest config and then exits. (https://jestjs.io/docs/en/cli#--showconfig)", - "type": "boolean" - }, - "silent": { - "description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/cli#--silent)", - "type": "boolean" - }, - "testNamePattern": { - "alias": "t", - "description": "Run only tests with a name that matches the regex pattern. (https://jestjs.io/docs/cli#--testnamepatternregex)", - "type": "string" - }, - "testPathIgnorePatterns": { - "description": "An array of regexp pattern strings that is matched against all tests paths before executing the test. Only run those tests with a path that does not match with the provided regexp expressions. (https://jestjs.io/docs/cli#--testpathignorepatternsregexarray)", - "type": "array", - "items": { "type": "string" } - }, - "testPathPattern": { - "description": "An array of regexp pattern strings that is matched against all tests paths before executing the test. (https://jestjs.io/docs/cli#--testpathpatternregex)", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "colors": { - "description": "Forces test results output highlighting even if stdout is not a TTY. (https://jestjs.io/docs/cli#--colors)", - "type": "boolean" - }, - "reporters": { - "description": "Run tests with specified reporters. Reporter options are not available via CLI. Example with multiple reporters: `jest --reporters=\"default\" --reporters=\"jest-junit\"`. (https://jestjs.io/docs/cli#--reporters)", - "type": "array", - "items": { "type": "string" } - }, - "verbose": { - "description": "Display individual test results with the test suite hierarchy. (https://jestjs.io/docs/cli#--verbose)", - "type": "boolean" - }, - "coverageReporters": { - "description": "A list of reporter names that Jest uses when writing coverage reports. Any istanbul reporter.", - "type": "array", - "items": { "type": "string" } - }, - "coverageDirectory": { - "description": "The directory where Jest should output its coverage files.", - "type": "string" - }, - "testResultsProcessor": { - "description": "Node module that implements a custom results processor. (https://jestjs.io/docs/en/configuration#testresultsprocessor-string)", - "type": "string" - }, - "updateSnapshot": { - "alias": "u", - "description": "Use this flag to re-record snapshots. Can be used together with a test suite pattern or with `--testNamePattern` to re-record snapshot for test matching the pattern. (https://jestjs.io/docs/cli#--updatesnapshot)", - "type": "boolean" - }, - "useStderr": { - "description": "Divert all output to stderr.", - "type": "boolean" - }, - "watch": { - "description": "Watch files for changes and rerun tests related to changed files. If you want to re-run all tests when a file has changed, use the `--watchAll` option. (https://jestjs.io/docs/cli#--watch)", - "type": "boolean" - }, - "watchAll": { - "description": "Watch files for changes and rerun all tests when something changes. If you want to re-run only the tests that depend on the changed files, use the `--watch` option. (https://jestjs.io/docs/cli#--watchall)", - "type": "boolean" - }, - "testLocationInResults": { - "description": "Adds a location field to test results. Used to report location of a test in a reporter. { \"column\": 4, \"line\": 5 } (https://jestjs.io/docs/cli#--testlocationinresults)", - "type": "boolean" - }, - "testTimeout": { - "description": "Default timeout of a test in milliseconds. Default value: `5000`. (https://jestjs.io/docs/cli#--testtimeoutnumber)", - "type": "number" - } - }, - "additionalProperties": false, - "required": ["target", "jestConfig"], - "presets": [] - }, - "description": "Creates and runs the E2E tests for an Nx Plugin.", - "x-deprecated": "@nx/plugin:e2e is deprecated and will be removed in Nx v19. Use @nx/jest:jest instead.", - "aliases": [], - "hidden": false, - "path": "/packages/plugin/src/executors/e2e/schema.json", - "type": "executor" -} diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 301e17e17966a..793075a991ed0 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -562,8 +562,6 @@ - [plugin](/nx-api/plugin) - [documents](/nx-api/plugin/documents) - [Overview](/nx-api/plugin/documents/overview) - - [executors](/nx-api/plugin/executors) - - [e2e](/nx-api/plugin/executors/e2e) - [generators](/nx-api/plugin/generators) - [plugin](/nx-api/plugin/generators/plugin) - [create-package](/nx-api/plugin/generators/create-package) diff --git a/nx-dev/nx-dev-e2e/src/packages.spec.ts b/nx-dev/nx-dev-e2e/src/packages.spec.ts index 1ec98e04e5a72..85d13d9b3a9b4 100644 --- a/nx-dev/nx-dev-e2e/src/packages.spec.ts +++ b/nx-dev/nx-dev-e2e/src/packages.spec.ts @@ -275,7 +275,6 @@ const pages: Array<{ title: string; path: string }> = [ title: '@nx/plugin:executor', path: '/packages/plugin/generators/executor', }, - { title: '@nx/plugin:e2e', path: '/packages/plugin/executors/e2e' }, { title: '@nx/react', path: '/packages/react' }, { title: '@nx/react:init', path: '/packages/react/generators/init' }, { diff --git a/packages/cypress/migrations.json b/packages/cypress/migrations.json index b3d3cbc3cad2c..08f02a5c75547 100644 --- a/packages/cypress/migrations.json +++ b/packages/cypress/migrations.json @@ -1,29 +1,5 @@ { "generators": { - "add-cypress-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Stop hashing cypress spec files and config files for build targets and dependent tasks", - "factory": "./src/migrations/update-15-0-0/add-cypress-inputs" - }, - "update-cy-mount-usage": { - "cli": "nx", - "version": "15.0.0-beta.4", - "description": "Update to using cy.mount in the commands.ts file instead of importing mount for each component test file", - "factory": "./src/migrations/update-15-0-0/update-cy-mount-usage" - }, - "update-to-cypress-11": { - "cli": "nx", - "version": "15.1.0-beta.0", - "description": "Update to Cypress v11. This migration will only update if the workspace is already on v10. https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/", - "factory": "./src/migrations/update-15-1-0/cypress-11" - }, - "update-to-cypress-12": { - "cli": "nx", - "version": "15.5.0-beta.0", - "description": "Update to Cypress v12. Cypress 12 contains a handful of breaking changes that might causes tests to start failing that nx cannot directly fix. Read more Cypress 12 changes: https://docs.cypress.io/guides/references/migration-guide#Migrating-to-Cypress-12-0.This migration will only run if you are already using Cypress v11.", - "factory": "./src/migrations/update-15-5-0/update-to-cypress-12" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", diff --git a/packages/cypress/src/migrations/update-15-0-0/__snapshots__/update-cy-mount-usage.spec.ts.snap b/packages/cypress/src/migrations/update-15-0-0/__snapshots__/update-cy-mount-usage.spec.ts.snap deleted file mode 100644 index 110592b225373..0000000000000 --- a/packages/cypress/src/migrations/update-15-0-0/__snapshots__/update-cy-mount-usage.spec.ts.snap +++ /dev/null @@ -1,221 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`update cy.mount usage should add the mount command 1`] = ` -"import { mount } from 'cypress/angular' -/// - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) - -Cypress.Commands.add('mount', mount);" -`; - -exports[`update cy.mount usage should update angular ct test file 1`] = ` -" - import { MountConfig } from 'cypress/angular'; - - describe('MyComponent', () => { - it('should work', () => { - cy.mount(MyComponent); - }); - - it('should work with config', () => { - cy.mount(MyComponent, {...config, componentProperties: {foo: 'bar'}}); - }); - }); - " -`; - -exports[`update cy.mount usage should update angular react test file 1`] = ` -" - - - describe('MyComponent', () => { - it('should work', () => { - cy.mount(); - }); - - it('should work with config', () => { - cy.mount(,); - }); - }); - " -`; - -exports[`update cy.mount usage should update angular react18 test file 1`] = ` -" - - - describe('MyComponent', () => { - it('should work', () => { - cy.mount(); - }); - - it('should work with config', () => { - cy.mount(); - }); - }); - " -`; - -exports[`update cy.mount usage should work 1`] = ` -"import { mount } from 'cypress/angular'; - -// eslint-disable-next-line @typescript-eslint/no-namespace -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -Cypress.Commands.add('mount', mount); -" -`; - -exports[`update cy.mount usage should work 2`] = ` -"import { MountConfig } from 'cypress/angular'; - -describe('MyComponent', () => { - it('should work', () => { - cy.mount(); - }); - - it('should work with config', () => { - cy.mount(); - }); -}); -" -`; - -exports[`update cy.mount usage should work 3`] = ` -"import { MountConfig } from 'cypress/angular'; - -describe('MyComponent', () => { - it('should work', () => { - cy.mount(); - }); - - it('should work with config', () => { - cy.mount(); - }); -}); -" -`; - -exports[`update cy.mount usage should work 4`] = ` -"import { MountConfig } from 'cypress/angular'; - -describe('MyComponent', () => { - it('should work', () => { - cy.mount(MyComponent); - }); - - it('should work with config', () => { - cy.mount(MyComponent, { ...config, componentProperties: { foo: 'bar' } }); - }); -}); -" -`; - -exports[`update cy.mount usage should work 5`] = ` -"// eslint-disable-next-line @typescript-eslint/no-namespace -declare namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount(c: any): void; - } -} - -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -Cypress.Commands.add('mount', (any) => { - console.log(mount); -}); -" -`; - -exports[`update cy.mount usage should work 6`] = ` -"describe('MyComponent', () => { - it('should work', () => { - cy.mount(); - }); - - it('should work with config', () => { - cy.mount(); - }); -}); -" -`; - -exports[`update cy.mount usage should work 7`] = ` -"describe('MyComponent', () => { - it('should work', () => { - cy.mount(); - }); - - it('should work with config', () => { - cy.mount(); - }); -}); -" -`; - -exports[`update cy.mount usage should work 8`] = ` -"describe('MyComponent', () => { - it('should work', () => { - cy.mount(MyComponent); - }); - - it('should work with config', () => { - cy.mount(MyComponent, { ...config, componentProperties: { foo: 'bar' } }); - }); -}); -" -`; diff --git a/packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.spec.ts b/packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.spec.ts deleted file mode 100644 index b2f05e9c49ca1..0000000000000 --- a/packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.spec.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readNxJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import addCypressInputs from './add-cypress-inputs'; - -describe('15.0.0 migration (add-cypress-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add inputs configuration for cypress targets', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - e2e: { - executor: '@nrwl/cypress:cypress', - options: {}, - }, - e2e2: { - executor: '@nrwl/cypress:cypress', - options: {}, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - tree.write('jest.preset.js', ''); - - await addCypressInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [], - }, - "targetDefaults": { - "e2e": { - "inputs": [ - "default", - "^production", - ], - }, - "e2e2": { - "inputs": [ - "default", - "^production", - ], - }, - }, - } - `); - }); - - it('should inputs configuration for cypress component testing targets', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - e2e: { - executor: '@nrwl/cypress:cypress', - options: { - testingType: 'component', - }, - }, - e2e2: { - executor: '@nrwl/cypress:cypress', - options: { - testingType: 'component', - }, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - tree.write('jest.preset.js', ''); - - await addCypressInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - "!{projectRoot}/cypress/**/*", - "!{projectRoot}/**/*.cy.[jt]s?(x)", - "!{projectRoot}/cypress.config.[jt]s", - ], - "sharedGlobals": [], - }, - "targetDefaults": { - "e2e": { - "inputs": [ - "default", - "^production", - ], - }, - "e2e2": { - "inputs": [ - "default", - "^production", - ], - }, - }, - } - `); - }); -}); diff --git a/packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.ts b/packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.ts deleted file mode 100644 index 9f45763ce8df0..0000000000000 --- a/packages/cypress/src/migrations/update-15-0-0/add-cypress-inputs.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { formatFiles, readNxJson, Tree, updateNxJson } from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl'; - -export default async function (tree: Tree) { - const nxJson = readNxJson(tree); - - const { cypressTargets, hasComponentTesting } = getCypressTargetNames(tree); - const hasProductionFileset = !!nxJson.namedInputs?.production; - - if (hasComponentTesting && hasProductionFileset && cypressTargets.size > 0) { - const productionFileset = new Set(nxJson.namedInputs.production); - for (const exclusion of [ - '!{projectRoot}/cypress/**/*', - '!{projectRoot}/**/*.cy.[jt]s?(x)', - '!{projectRoot}/cypress.config.[jt]s', - ]) { - productionFileset.add(exclusion); - } - nxJson.namedInputs.production = Array.from(productionFileset); - } - - for (const targetName of cypressTargets) { - nxJson.targetDefaults ??= {}; - const cypressTargetDefaults = (nxJson.targetDefaults[targetName] ??= {}); - - cypressTargetDefaults.inputs ??= [ - 'default', - hasProductionFileset ? '^production' : '^default', - ]; - } - - updateNxJson(tree, nxJson); - - await formatFiles(tree); -} - -function getCypressTargetNames(tree: Tree) { - const cypressTargets = new Set(); - let hasComponentTesting = false; - forEachExecutorOptions( - tree, - '@nrwl/cypress:cypress', - (options, __, target) => { - cypressTargets.add(target); - if (options.testingType === 'component') { - hasComponentTesting = true; - } - } - ); - return { cypressTargets, hasComponentTesting }; -} diff --git a/packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.spec.ts b/packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.spec.ts deleted file mode 100644 index a4b38ec09307e..0000000000000 --- a/packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.spec.ts +++ /dev/null @@ -1,338 +0,0 @@ -import { installedCypressVersion } from '../../utils/cypress-version'; -import { - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addMountCommand, - updateCyFile, - updateCyMountUsage, -} from './update-cy-mount-usage'; -import { libraryGenerator } from '@nx/js'; -import cypressComponentConfiguration from '../../generators/component-configuration/component-configuration'; - -jest.mock('../../utils/cypress-version'); -// nested code imports graph from the repo, which might have innacurate graph version -jest.mock('nx/src/project-graph/project-graph', () => ({ - ...jest.requireActual('nx/src/project-graph/project-graph'), - createProjectGraphAsync: jest - .fn() - .mockImplementation(async () => ({ nodes: {}, dependencies: {} })), -})); - -describe('update cy.mount usage', () => { - let tree: Tree; - let mockedInstalledCypressVersion: jest.Mock< - ReturnType - > = installedCypressVersion as never; - // TODO(@leosvelperez): Turn these tests back to adding the plugin - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - mockedInstalledCypressVersion.mockReturnValue(10); - }); - - it('should work', async () => { - await setup(tree); - await updateCyMountUsage(tree); - - expect( - tree.read('libs/my-lib/cypress/support/commands.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/lib/my-cmp-one.cy.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/lib/my-cmp-two.cy.tsx', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/lib/my-cmp-three.cy.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/another-lib/cypress/support/commands.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/another-lib/src/lib/my-cmp-one.cy.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/another-lib/src/lib/my-cmp-two.cy.tsx', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/another-lib/src/lib/my-cmp-three.cy.ts', 'utf-8') - ).toMatchSnapshot(); - }); - - it('should add the mount command', async () => { - tree.write( - 'apps/my-app/cypress/support/commands.ts', - `/// - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - } - } -} - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -` - ); - addMountCommand(tree, 'apps/my-app', 'angular'); - expect( - tree.read('apps/my-app/cypress/support/commands.ts', 'utf-8') - ).toMatchSnapshot(); - }); - - it('should update angular ct test file', () => { - tree.write( - 'my-file.cy.ts', - ` - import { MountConfig, mount } from 'cypress/angular'; - - describe('MyComponent', () => { - it('should work', () => { - mount(MyComponent); - }); - - it('should work with config', () => { - mount(MyComponent, {...config, componentProperties: {foo: 'bar'}}); - }); - }); - ` - ); - updateCyFile(tree, 'my-file.cy.ts', 'angular'); - - expect(tree.read('my-file.cy.ts', 'utf-8')).toMatchSnapshot(); - }); - it('should update angular react18 test file', () => { - tree.write( - 'my-file.cy.ts', - ` - import { mount } from 'cypress/react18'; - - describe('MyComponent', () => { - it('should work', () => { - mount(); - }); - - it('should work with config', () => { - mount(); - }); - }); - ` - ); - updateCyFile(tree, 'my-file.cy.ts', 'react18'); - - expect(tree.read('my-file.cy.ts', 'utf-8')).toMatchSnapshot(); - }); - it('should update angular react test file', () => { - tree.write( - 'my-file.cy.ts', - ` - import { mount } from 'cypress/react'; - - describe('MyComponent', () => { - it('should work', () => { - mount(); - }); - - it('should work with config', () => { - mount(,); - }); - }); - ` - ); - updateCyFile(tree, 'my-file.cy.ts', 'react'); - - expect(tree.read('my-file.cy.ts', 'utf-8')).toMatchSnapshot(); - }); -}); - -async function setup(tree: Tree) { - await libraryGenerator(tree, { name: 'my-lib' }); - await libraryGenerator(tree, { name: 'another-lib' }); - await cypressComponentConfiguration(tree, { - project: 'my-lib', - skipFormat: false, - }); - await cypressComponentConfiguration(tree, { - project: 'another-lib', - skipFormat: false, - }); - const myLib = readProjectConfiguration(tree, 'my-lib'); - myLib.targets['build'] = { - executor: '@nrwl/angular:webpack-browser', - options: {}, - }; - myLib.targets['component-test'].executor = '@nrwl/cypress:cypress'; - myLib.targets['component-test'].options.devServerTarget = 'my-lib:build'; - updateProjectConfiguration(tree, 'my-lib', myLib); - const anotherLib = readProjectConfiguration(tree, 'another-lib'); - anotherLib.targets['build'] = { - executor: '@nrwl/webpack:webpack', - options: {}, - }; - anotherLib.targets['component-test'].executor = '@nrwl/cypress:cypress'; - anotherLib.targets['component-test'].options.devServerTarget = - 'another-lib:build'; - updateProjectConfiguration(tree, 'another-lib', anotherLib); - tree.write( - 'libs/my-lib/cypress/support/commands.ts', - ` -// eslint-disable-next-line @typescript-eslint/no-namespace -declare namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - } -} - -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -});` - ); - tree.write( - 'libs/my-lib/src/lib/my-cmp-one.cy.js', - `const { mount } =require('cypress/react'); - - describe('MyComponent', () => { - it('should work', () => { - mount(); - }); - - it('should work with config', () => { - mount(,); - }); - }); - ` - ); - tree.write( - 'libs/my-lib/src/lib/my-cmp-two.cy.tsx', - `import { mount } from 'cypress/react18'; - - describe('MyComponent', () => { - it('should work', () => { - mount(); - }); - - it('should work with config', () => { - mount(,); - }); - }); - ` - ); - tree.write( - 'libs/my-lib/src/lib/my-cmp-three.cy.ts', - `import { mount, MountConfig } from 'cypress/angular'; - - describe('MyComponent', () => { - it('should work', () => { - mount(MyComponent); - }); - - it('should work with config', () => { - mount(MyComponent, {...config, componentProperties: {foo: 'bar'}}); - }); - }); - ` - ); - - tree.write( - 'libs/another-lib/cypress/support/commands.ts', - ` -// eslint-disable-next-line @typescript-eslint/no-namespace -declare namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount(c: any): void; - } -} - -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -Cypress.Commands.add('mount', (any) => { - console.log(mount); -}); -` - ); - - tree.write( - 'libs/another-lib/src/lib/my-cmp-one.cy.js', - `const { mount } = require('cypress/react'); - - describe('MyComponent', () => { - it('should work', () => { - mount(); - }); - - it('should work with config', () => { - mount(,); - }); - }); - ` - ); - tree.write( - 'libs/another-lib/src/lib/my-cmp-two.cy.tsx', - `import { mount } from 'cypress/react18'; - - describe('MyComponent', () => { - it('should work', () => { - mount(); - }); - - it('should work with config', () => { - mount(,); - }); - }); - ` - ); - tree.write( - 'libs/another-lib/src/lib/my-cmp-three.cy.ts', - `import { mount, MountConfig } from 'cypress/angular'; - - describe('MyComponent', () => { - it('should work', () => { - mount(MyComponent); - }); - - it('should work with config', () => { - mount(MyComponent, {...config, componentProperties: {foo: 'bar'}}); - }); - }); - ` - ); -} diff --git a/packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.ts b/packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.ts deleted file mode 100644 index e36c078f0e361..0000000000000 --- a/packages/cypress/src/migrations/update-15-0-0/update-cy-mount-usage.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl'; -import { CY_FILE_MATCHER } from '../../utils/ct-helpers'; -import { installedCypressVersion } from '../../utils/cypress-version'; -import { - createProjectGraphAsync, - formatFiles, - getProjects, - joinPathFragments, - parseTargetString, - readJson, - TargetConfiguration, - Tree, - visitNotIgnoredFiles, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { checkAndCleanWithSemver } from '@nx/devkit/src/utils/semver'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { gte } from 'semver'; -import * as ts from 'typescript'; - -export async function updateCyMountUsage(tree: Tree) { - if (installedCypressVersion() < 10) { - return; - } - - const projects = getProjects(tree); - const graph = await createProjectGraphAsync(); - - forEachExecutorOptions( - tree, - '@nrwl/cypress:cypress', - (options, projectName) => { - if (options.testingType !== 'component' || !options.devServerTarget) { - return; - } - - const parsed = parseTargetString(options.devServerTarget, graph); - if (!parsed?.project || !parsed?.target) { - return; - } - - const buildProjectConfig = projects.get(parsed.project); - const framework = getFramework( - tree, - parsed.configuration - ? buildProjectConfig.targets[parsed.target].configurations[ - parsed.configuration - ] - : buildProjectConfig.targets[parsed.target] - ); - - const ctProjectConfig = projects.get(projectName); - addMountCommand(tree, ctProjectConfig.root, framework); - visitNotIgnoredFiles(tree, ctProjectConfig.sourceRoot, (filePath) => { - if (CY_FILE_MATCHER.test(filePath)) { - updateCyFile(tree, filePath, framework); - } - }); - } - ); - - await formatFiles(tree); -} - -export function addMountCommand( - tree: Tree, - projectRoot: string, - framework: string -) { - const commandFilePath = joinPathFragments( - projectRoot, - 'cypress', - 'support', - 'commands.ts' - ); - if (!tree.exists(commandFilePath)) { - return; - } - - const commandFile = tree.read(commandFilePath, 'utf-8'); - const mountCommand = tsquery.query( - commandFile, - 'CallExpression:has(StringLiteral[value="mount"]) PropertyAccessExpression:has(Identifier[name="add"])' - ); - if (mountCommand?.length > 0) { - return; - } - const existingCommands = tsquery.query< - ts.MethodSignature | ts.PropertySignature - >( - commandFile, - 'InterfaceDeclaration:has(Identifier[name="Chainable"]) > MethodSignature, InterfaceDeclaration:has(Identifier[name="Chainable"]) > PropertySignature' - ); - const isGlobalDeclaration = tsquery.query( - commandFile, - 'ModuleDeclaration > Identifier[name="global"]' - ); - - const updatedInterface = tsquery.replace( - commandFile, - 'ModuleDeclaration:has(Identifier[name="Cypress"])', - (node: ts.ModuleDeclaration) => { - const newModuleDelcaration = `declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - ${existingCommands.map((c) => c.getText()).join('\n')} - mount: typeof mount; - } - } -}`; - /* - * this is to prevent the change being applied twice since - * declare global { 1 - * interface Cypress { 2 - * } - * } - * matches twice. - * i.e. if there is no global declaration, then add it - * or if the node is the global declaration, then add it, - * but not to the cypress module declaration inside the global declaration - */ - if ( - isGlobalDeclaration?.length === 0 || - node.name.getText() === 'global' - ) { - return newModuleDelcaration; - } - } - ); - - const updatedCommandFile = `import { mount } from 'cypress/${framework}'\n${updatedInterface}\nCypress.Commands.add('mount', mount);`; - tree.write(commandFilePath, updatedCommandFile); -} - -function getFramework( - tree: Tree, - target: TargetConfiguration -): 'angular' | 'react' | 'react18' { - if ( - target.executor === '@nrwl/angular:webpack-browser' || - target.executor === '@angular-devkit/build-angular:browser' - ) { - return 'angular'; - } - - const pkgJson = readJson(tree, 'package.json'); - const reactDomVersion = pkgJson?.dependencies?.['react-dom']; - const hasReact18 = - reactDomVersion && - gte(checkAndCleanWithSemver('react-dom', reactDomVersion), '18.0.0'); - - if (hasReact18) { - return 'react18'; - } - - return 'react'; -} - -export function updateCyFile( - tree: Tree, - filePath: string, - framework: 'angular' | 'react' | 'react18' -) { - if (!tree.exists(filePath)) { - return; - } - - const contents = tree.read(filePath, 'utf-8'); - const withCyMount = tsquery.replace( - contents, - ':matches(CallExpression>Identifier[name="mount"])', - (node: ts.CallExpression) => { - return `cy.mount`; - } - ); - const withUpdatedImports = tsquery.replace( - withCyMount, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="mount"]):has(StringLiteral[value="cypress/react"], StringLiteral[value="cypress/angular"], StringLiteral[value="cypress/react18"])', - (node: ts.ImportDeclaration) => { - switch (framework) { - case 'angular': - return `import { MountConfig } from 'cypress/angular';`; - case 'react18': - case 'react': - return ' '; // have to return non falsy string to remove the node - default: - return node.getText().replace('mount', ''); - } - } - ); - - tree.write(filePath, withUpdatedImports); -} - -export default updateCyMountUsage; diff --git a/packages/cypress/src/migrations/update-15-1-0/__snapshots__/cypress-11.spec.ts.snap b/packages/cypress/src/migrations/update-15-1-0/__snapshots__/cypress-11.spec.ts.snap deleted file mode 100644 index 965d90596ea37..0000000000000 --- a/packages/cypress/src/migrations/update-15-1-0/__snapshots__/cypress-11.spec.ts.snap +++ /dev/null @@ -1,198 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Cypress 11 Migration should migrate to v11 1`] = ` -"it('calls the prop', () => { - cy.mount(); - cy.contains('My component'); -}); - -describe('again', () => { - it('calls the prop', () => { - cy.mount(); - cy.contains('My component'); - }); -}); -" -`; - -exports[`Cypress 11 Migration should migrate to v11 2`] = ` -"/** TODO: mountHook is deprecate. - * Use a wrapper component instead. - * See post for details: https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/#reactmounthook-removed - * */ -import { mountHook, getContainerEl } from 'cypress/react18'; -import ReactDom from 'react-dom'; -import { useCounter } from './useCounter'; - -it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0); - result.current.increment(); - expect(result.current.count).to.equal(1); - result.current.increment(); - expect(result.current.count).to.equal(2); - }); -}); - -describe('blah', () => { - it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0); - result.current.increment(); - expect(result.current.count).to.equal(1); - result.current.increment(); - expect(result.current.count).to.equal(2); - }); - }); -}); - -it('calls the prop', () => { - cy.mount(); - cy.contains('My component'); - - cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl())); - - cy.contains('My component').should('not.exist'); - cy.get('@onUnmount').should('have.been.calledOnce'); -}); - -describe('again', () => { - it('calls the prop', () => { - cy.mount(); - cy.contains('My component'); - - cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl())); - - cy.contains('My component').should('not.exist'); - cy.get('@onUnmount').should('have.been.calledOnce'); - }); -}); -" -`; - -exports[`Cypress 11 Migration should migrate to v11 3`] = ` -"/** TODO: mountHook is deprecate. - * Use a wrapper component instead. - * See post for details: https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/#reactmounthook-removed - * */ -import { mountHook, getContainerEl } from 'cypress/react'; -import ReactDom from 'react-dom'; -import { useCounter } from './useCounter'; - -it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0); - result.current.increment(); - expect(result.current.count).to.equal(1); - result.current.increment(); - expect(result.current.count).to.equal(2); - }); -}); - -describe('blah', () => { - it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0); - result.current.increment(); - expect(result.current.count).to.equal(1); - result.current.increment(); - expect(result.current.count).to.equal(2); - }); - }); -}); - -it('calls the prop', () => { - cy.mount(); - cy.contains('My component'); - - cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl())); - - cy.contains('My component').should('not.exist'); - cy.get('@onUnmount').should('have.been.calledOnce'); -}); - -describe('again', () => { - it('calls the prop', () => { - cy.mount(); - cy.contains('My component'); - - cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl())); - - cy.contains('My component').should('not.exist'); - cy.get('@onUnmount').should('have.been.calledOnce'); - }); -}); -" -`; - -exports[`Cypress 11 Migration should migrate to v11 4`] = ` -"import { TestBed } from '@angular/core/testing'; - -import { MyComponent } from './my.component'; -describe('MyComponent', () => { - const config = { - imports: [], - declarations: [], - providers: [{ provide: 'foo', useValue: 'bar' }], - }; - it('direct usage', () => { - TestBed.overrideComponent(MyComponent, { - add: { providers: config.providers }, - }); - cy.mount(MyComponent, config); - }); - it('spread usage', () => { - TestBed.overrideComponent(MyComponent, { - add: { providers: [{ provide: 'foo', useValue: 'bar' }] }, - }); - cy.mount(MyComponent, { ...config, providers: undefined }); - }); - it('inlined usage', () => { - TestBed.overrideComponent(MyComponent, { - add: { providers: [{ provide: 'foo', useValue: 'bar' }] }, - }); - cy.mount(MyComponent, { - imports: [], - declarations: [], - providers: undefined, - }); - }); -}); -" -`; - -exports[`Cypress 11 Migration should migrate to v11 5`] = ` -"import { MountConfig } from 'cypress/angular'; -import { MyComponent } from './my.component'; -import { TestBed } from '@angular/core/testing'; -describe('MyComponent', () => { - const config: MountConfig = { - imports: [], - declarations: [], - providers: [{ provide: 'foo', useValue: 'bar' }], - }; - it('direct usage', () => { - TestBed.overrideComponent(MyComponent, { - add: { providers: config.providers }, - }); - cy.mount(MyComponent, config); - }); - it('spread usage', () => { - TestBed.overrideComponent(MyComponent, { - add: { providers: [{ provide: 'foo', useValue: 'bar' }] }, - }); - cy.mount(MyComponent, { ...config, providers: undefined }); - }); - it('inlined usage', () => { - TestBed.overrideComponent(MyComponent, { - add: { providers: [{ provide: 'foo', useValue: 'bar' }] }, - }); - cy.mount(MyComponent, { - imports: [], - declarations: [], - providers: undefined, - }); - }); -}); -" -`; diff --git a/packages/cypress/src/migrations/update-15-1-0/cypress-11.spec.ts b/packages/cypress/src/migrations/update-15-1-0/cypress-11.spec.ts deleted file mode 100644 index ec83540f2f87c..0000000000000 --- a/packages/cypress/src/migrations/update-15-1-0/cypress-11.spec.ts +++ /dev/null @@ -1,344 +0,0 @@ -import 'nx/src/internal-testing-utils/mock-project-graph'; - -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { libraryGenerator } from '@nx/js'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import updateToCypress11 from './cypress-11'; -import { installedCypressVersion } from '../../utils/cypress-version'; - -jest.mock('../../utils/cypress-version'); -import cypressComponentConfiguration from '../../generators/component-configuration/component-configuration'; - -describe('Cypress 11 Migration', () => { - let tree: Tree; - let mockInstalledCypressVersion: jest.Mock< - ReturnType - > = installedCypressVersion as never; - - // TODO(@leosvelperez): Turn this back to adding the plugin - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should not update if cypress { - // setup called the component setup. mock to v10 so it doesn't throw. - mockInstalledCypressVersion.mockReturnValue(10); - await setup(tree); - mockInstalledCypressVersion.mockReturnValue(9); - const beforeReact = tree.read( - 'libs/my-react-lib/src/lib/no-import.cy.ts', - 'utf-8' - ); - - const beforeNg = tree.read( - 'libs/my-ng-lib/src/lib/no-import.component.cy.ts', - 'utf-8' - ); - - await updateToCypress11(tree); - const actualReact = tree.read( - 'libs/my-react-lib/src/lib/no-import.cy.ts', - 'utf-8' - ); - - const actualNg = tree.read( - 'libs/my-ng-lib/src/lib/no-import.component.cy.ts', - 'utf-8' - ); - - expect(actualReact).toEqual(beforeReact); - expect(actualNg).toEqual(beforeNg); - }); - - it('should migrate to v11', async () => { - mockInstalledCypressVersion.mockReturnValue(10); - await setup(tree); - await updateToCypress11(tree); - expect( - tree.read('libs/my-react-lib/src/lib/no-import.cy.ts', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read( - 'libs/my-react-lib/src/lib/with-import-18.component.cy.ts', - 'utf-8' - ) - ).toMatchSnapshot(); - expect( - tree.read( - 'libs/my-react-lib/src/lib/with-import.component.cy.ts', - 'utf-8' - ) - ).toMatchSnapshot(); - expect( - tree.read('libs/my-ng-lib/src/lib/no-import.component.cy.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-ng-lib/src/lib/with-import.component.cy.ts', 'utf-8') - ).toMatchSnapshot(); - }); - - it('should only update component projects', async () => { - addProjectConfiguration(tree, 'my-e2e-app', { - projectType: 'application', - root: 'apps/my-e2e-app', - sourceRoot: 'apps/my-e2e-app/src', - targets: { - e2e: { - executor: '@nrwl/cypress:cypress', - options: { - cypressConfig: 'apps/my-e2e-app/cypress.config.ts', - }, - }, - }, - }); - - const content = `import { MountConfig } from 'cypress/angular'; -import { MyComponent } from './my.component'; -describe('MyComponent', () => { - const config: MountConfig = { - imports: [], - declarations: [], - providers: [{ provide: 'foo', useValue: 'bar' }], - }; - it('direct usage', () => { - cy.mount(MyComponent, config); - }); -}); -`; - tree.write('apps/my-e2e-app/src/somthing.component.cy.ts', content); - await updateToCypress11(tree); - expect( - tree.read('apps/my-e2e-app/src/somthing.component.cy.ts', 'utf-8') - ).toEqual(content); - }); -}); - -async function setup(tree: Tree) { - await libraryGenerator(tree, { - name: 'my-react-lib', - }); - await cypressComponentConfiguration(tree, { - project: 'my-react-lib', - skipFormat: true, - }); - const projectConfig = readProjectConfiguration(tree, 'my-react-lib'); - projectConfig.targets['component-test'].executor = '@nrwl/cypress:cypress'; - updateProjectConfiguration(tree, 'my-react-lib', projectConfig); - tree.write( - 'libs/my-react-lib/cypress/support/commands.ts', - `/// -import { mount } from 'cypress/react18' - -declare global { -// eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} -Cypress.Commands.add('mount', mount) -` - ); - tree.write( - 'libs/my-react-lib/src/lib/no-import.cy.ts', - ` -it('calls the prop', () => { - cy.mount() - cy.contains('My component') -}) - -describe('again', () => { - it('calls the prop', () => { - cy.mount() - cy.contains('My component') - }) -})` - ); - tree.write( - 'libs/my-react-lib/src/lib/with-import.component.cy.ts', - `import { mountHook, unmount } from 'cypress/react' -import { useCounter } from './useCounter' - -it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0) - result.current.increment() - expect(result.current.count).to.equal(1) - result.current.increment() - expect(result.current.count).to.equal(2) - }) -}) - -describe('blah', () => { - - it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0) - result.current.increment() - expect(result.current.count).to.equal(1) - result.current.increment() - expect(result.current.count).to.equal(2) - }) - }) -}) - - -it('calls the prop', () => { - cy.mount() - cy.contains('My component') - - unmount() - - cy.contains('My component').should('not.exist') - cy.get('@onUnmount').should('have.been.calledOnce') -}) - -describe('again', () => { - it('calls the prop', () => { - cy.mount() - cy.contains('My component') - - unmount() - - cy.contains('My component').should('not.exist') - cy.get('@onUnmount').should('have.been.calledOnce') - }) -})` - ); - tree.write( - 'libs/my-react-lib/src/lib/with-import-18.component.cy.ts', - `import { mountHook, unmount } from 'cypress/react18'; -import { useCounter } from './useCounter'; - -it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0) - result.current.increment() - expect(result.current.count).to.equal(1) - result.current.increment() - expect(result.current.count).to.equal(2) - }) -}) - -describe('blah', () => { - - it('increments the count', () => { - mountHook(() => useCounter()).then((result) => { - expect(result.current.count).to.equal(0) - result.current.increment() - expect(result.current.count).to.equal(1) - result.current.increment() - expect(result.current.count).to.equal(2) - }) - }) -}) - - -it('calls the prop', () => { - cy.mount() - cy.contains('My component') - - unmount() - - cy.contains('My component').should('not.exist') - cy.get('@onUnmount').should('have.been.calledOnce') -}) - -describe('again', () => { - it('calls the prop', () => { - cy.mount() - cy.contains('My component') - - unmount() - - cy.contains('My component').should('not.exist') - cy.get('@onUnmount').should('have.been.calledOnce') - }) -})` - ); - - await libraryGenerator(tree, { - name: 'my-ng-lib', - }); - - await cypressComponentConfiguration(tree, { - project: 'my-ng-lib', - skipFormat: true, - }); - const projectConfig2 = readProjectConfiguration(tree, 'my-ng-lib'); - projectConfig2.targets['component-test'].executor = '@nrwl/cypress:cypress'; - updateProjectConfiguration(tree, 'my-ng-lib', projectConfig2); - tree.write( - 'libs/my-ng-lib/cypress/support/commands.ts', - `/// -import { mount } from 'cypress/angular' - -declare global { -// eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} -Cypress.Commands.add('mount', mount) -` - ); - tree.write( - 'libs/my-ng-lib/src/lib/with-import.component.cy.ts', - `import { MountConfig } from 'cypress/angular'; - import { MyComponent } from './my.component'; - import {TestBed} from '@angular/core/testing'; - describe('MyComponent', () => { - const config: MountConfig = { - imports: [], - declarations: [], - providers: [{provide: 'foo', useValue: 'bar'}] - }; - it('direct usage', () => { - cy.mount(MyComponent, config); - }); - it('spread usage', () => { - cy.mount(MyComponent, {...config, providers: [{provide: 'foo', useValue: 'bar'}] }); - }); - it('inlined usage', () => { - cy.mount(MyComponent, {imports: [], declarations: [], providers: [{provide: 'foo', useValue: 'bar'}]}); - }); - }); - ` - ); - tree.write( - 'libs/my-ng-lib/src/lib/no-import.component.cy.ts', - ` - import { MyComponent } from './my.component'; - describe('MyComponent', () => { - const config = { - imports: [], - declarations: [], - providers: [{provide: 'foo', useValue: 'bar'}] - }; - it('direct usage', () => { - cy.mount(MyComponent, config); - }); - it('spread usage', () => { - cy.mount(MyComponent, {...config, providers: [{provide: 'foo', useValue: 'bar'}] }); - }); - it('inlined usage', () => { - cy.mount(MyComponent, {imports: [], declarations: [], providers: [{provide: 'foo', useValue: 'bar'}]}); - }); - }); - ` - ); -} diff --git a/packages/cypress/src/migrations/update-15-1-0/cypress-11.ts b/packages/cypress/src/migrations/update-15-1-0/cypress-11.ts deleted file mode 100644 index f116000445022..0000000000000 --- a/packages/cypress/src/migrations/update-15-1-0/cypress-11.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { CY_FILE_MATCHER } from '../../utils/ct-helpers'; -import { - addDependenciesToPackageJson, - formatFiles, - getProjects, - joinPathFragments, - Tree, - visitNotIgnoredFiles, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { extname } from 'path'; -import * as ts from 'typescript'; -import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl'; -import { installedCypressVersion } from '../../utils/cypress-version'; -import { cypressVersion } from '../../utils/versions'; - -export async function updateToCypress11(tree: Tree) { - const installedVersion = installedCypressVersion(); - if (installedVersion < 10) { - return; - } - - const projects = getProjects(tree); - forEachExecutorOptions( - tree, - '@nrwl/cypress:cypress', - (options, projectName, targetName, configurationName) => { - if ( - options.testingType !== 'component' || - !(options.cypressConfig && tree.exists(options.cypressConfig)) - ) { - return; - } - const projectConfig = projects.get(projectName); - const commandsFile = joinPathFragments( - projectConfig.root, - 'cypress', - 'support', - 'commands.ts' - ); - const framework = getFramework( - tree.exists(commandsFile) - ? tree.read(commandsFile, 'utf-8') - : tree.read(options.cypressConfig, 'utf-8') - ); - - visitNotIgnoredFiles(tree, projectConfig.sourceRoot, (filePath) => { - if (!CY_FILE_MATCHER.test(filePath)) { - return; - } - const frameworkFromFile = getFramework(tree.read(filePath, 'utf-8')); - - if (framework === 'react' || frameworkFromFile === 'react') { - updateUnmountUsage(tree, filePath); - updateMountHookUsage(tree, filePath); - } - if (framework === 'angular' || frameworkFromFile === 'angular') { - updateProviderUsage(tree, filePath); - } - }); - } - ); - - const installTask = addDependenciesToPackageJson( - tree, - {}, - { cypress: cypressVersion } - ); - - await formatFiles(tree); - return () => { - installTask(); - }; -} - -export function updateMountHookUsage(tree: Tree, filePath: string) { - const originalContents = tree.read(filePath, 'utf-8'); - const commentedMountHook = tsquery.replace( - originalContents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="mountHook"]):has(StringLiteral[value="cypress/react"], StringLiteral[value="cypress/react18"])', - (node) => { - return `/** TODO: mountHook is deprecate. -* Use a wrapper component instead. -* See post for details: https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/#reactmounthook-removed -* */\n${node.getText()}`; - } - ); - - tree.write(filePath, commentedMountHook); -} - -export function updateUnmountUsage(tree: Tree, filePath: string) { - const reactDomImport = extname(filePath).includes('ts') - ? `import ReactDom from 'react-dom'` - : `const ReactDom = require('react-dom')`; - - const originalContents = tree.read(filePath, 'utf-8'); - - const updatedImports = tsquery.replace( - originalContents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="unmount"]):has(StringLiteral[value="cypress/react"], StringLiteral[value="cypress/react18"])', - (node) => { - return `${node.getText().replace('unmount', 'getContainerEl')} -${reactDomImport}`; - } - ); - - const updatedUnmountApi = tsquery.replace( - updatedImports, - 'ExpressionStatement > CallExpression:has(Identifier[name="unmount"])', - (node: ts.ExpressionStatement) => { - if (node.expression.getText() === 'unmount') { - return `cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl()))`; - } - } - ); - - tree.write(filePath, updatedUnmountApi); -} - -export function updateProviderUsage(tree: Tree, filePath: string) { - const originalContents = tree.read(filePath, 'utf-8'); - const isTestBedImported = - tsquery.query( - originalContents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="TestBed"]):has(StringLiteral[value="@angular/core/testing"])' - )?.length > 0; - - let updatedProviders = tsquery.replace( - originalContents, - 'CallExpression:has(PropertyAccessExpression:has(Identifier[name="mount"]))', - (node: ts.CallExpression) => { - const expressionName = node.expression.getText(); - if (expressionName === 'cy.mount' && node?.arguments?.length > 1) { - const component = node.arguments[0].getText(); - - if (ts.isObjectLiteralExpression(node.arguments[1])) { - const providers = node.arguments[1]?.properties - ?.find((p) => p.name?.getText() === 'providers') - ?.getText(); - const noProviders = tsquery.replace( - node.getText(), - 'PropertyAssignment:has(Identifier[name="providers"])', - (n) => { - // set it to undefined so we don't run into a hanging comma causing invalid syntax - return 'providers: undefined'; - } - ); - return `TestBed.overrideComponent(${component}, { add: { ${providers} }});\n${noProviders}`; - } else { - return `TestBed.overrideComponent(${component}, {add: { providers: ${node.arguments[1].getText()}.providers}});\n${node.getText()}`; - } - } - } - ); - tree.write( - filePath, - `${ - isTestBedImported - ? '' - : "import {TestBed} from '@angular/core/testing';\n" - }${updatedProviders}` - ); -} - -function getFramework(contents: string): 'react' | 'angular' | null { - if (contents.includes('cypress/react') || contents.includes('@nrwl/react')) { - return 'react'; - } - if ( - contents.includes('cypress/angular') || - contents.includes('@nrwl/angular') - ) { - return 'angular'; - } - return null; -} - -export default updateToCypress11; diff --git a/packages/cypress/src/migrations/update-15-5-0/__snapshots__/update-to-cypress-12.spec.ts.snap b/packages/cypress/src/migrations/update-15-5-0/__snapshots__/update-to-cypress-12.spec.ts.snap deleted file mode 100644 index b6dfeb09c74f7..0000000000000 --- a/packages/cypress/src/migrations/update-15-5-0/__snapshots__/update-to-cypress-12.spec.ts.snap +++ /dev/null @@ -1,87 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Cypress 12 Migration should migrate to cy 12 1`] = ` -"describe('something', () => { - it('should do the thing', () => { - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes -Cypress.Cookies.defaults() - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes -Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -cy.server() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - /** -* TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. -* You should use .then() to chain commands instead. -* More Info: https://docs.cypress.io/guides/references/migration-guide#-should -**/ -cy.should(($s) => { - cy.get('@table').find('tr').should('have.length', 3) -}) - }) -})" -`; - -exports[`Cypress 12 Migration should migrate to cy 12 2`] = ` -"describe('something', () => { - it('should do the thing', () => { - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes -Cypress.Cookies.defaults() - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes -Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -cy.server() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - /** -* TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. -* You should use .then() to chain commands instead. -* More Info: https://docs.cypress.io/guides/references/migration-guide#-should -**/ -cy.should(($s) => { - cy.get('@table').find('tr').should('have.length', 3) -}) - }) -})" -`; diff --git a/packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.spec.ts b/packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.spec.ts deleted file mode 100644 index bcb16e454d7a1..0000000000000 --- a/packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.spec.ts +++ /dev/null @@ -1,717 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - stripIndents, - Tree, - readJson, -} from '@nx/devkit'; -import { - shouldNotOverrideCommands, - shouldNotUseCyInShouldCB, - shouldUseCyIntercept, - shouldUseCySession, - turnOffTestIsolation, - updateToCypress12, -} from './update-to-cypress-12'; -import { installedCypressVersion } from '../../utils/cypress-version'; -jest.mock('../../utils/cypress-version'); - -describe('Cypress 12 Migration', () => { - let tree: Tree; - let mockInstalledCypressVersion: jest.Mock< - ReturnType - > = installedCypressVersion as never; - beforeEach(() => { - tree = createTreeWithEmptyWorkspace(); - jest.resetAllMocks(); - }); - - it('should migrate to cy 12', () => { - mockInstalledCypressVersion.mockReturnValue(11); - addCypressProject(tree, 'my-app-e2e'); - addCypressProject(tree, 'my-other-app-e2e'); - updateToCypress12(tree); - assertMigration(tree, 'my-app-e2e'); - assertMigration(tree, 'my-other-app-e2e'); - const pkgJson = readJson(tree, 'package.json'); - expect(pkgJson.devDependencies['cypress']).toEqual('^12.2.0'); - }); - - it('should not migrate if cypress version is < 11', () => { - mockInstalledCypressVersion.mockReturnValue(10); - addCypressProject(tree, 'my-app-e2e'); - updateToCypress12(tree); - expect(tree.read('apps/my-app-e2e/cypress.config.ts', 'utf-8')) - .toMatchInlineSnapshot(` - "import { defineConfig } from 'cypress'; - import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - - export default defineConfig({ - e2e: nxE2EPreset(__filename) - })" - `); - }); - - describe('nest cypress commands in should callback', () => { - beforeEach(() => { - tree.write( - 'should-callback.ts', - `describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - cy.server() - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - cy.should((b) => { - const a = 123; - // I'm not doing nested cy stuff - }); - cy.should(($s) => { - cy.task(""); - }) - cy.should(function($el) { - cy.task(""); - }) - }) -}) -` - ); - }); - it('should comment', () => { - shouldNotUseCyInShouldCB(tree, 'should-callback.ts'); - expect(tree.read('should-callback.ts', 'utf-8')).toMatchInlineSnapshot(` - "describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - cy.server() - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - cy.should((b) => { - const a = 123; - // I'm not doing nested cy stuff - }); - /** - * TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. - * You should use .then() to chain commands instead. - * More Info: https://docs.cypress.io/guides/references/migration-guide#-should - **/ - cy.should(($s) => { - cy.task(""); - }) - /** - * TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. - * You should use .then() to chain commands instead. - * More Info: https://docs.cypress.io/guides/references/migration-guide#-should - **/ - cy.should(function($el) { - cy.task(""); - }) - }) - }) - " - `); - }); - - it('should be idempotent', () => { - const expected = `describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - cy.server() - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - cy.should((b) => { - const a = 123; - // I'm not doing nested cy stuff - }); - /** -* TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. -* You should use .then() to chain commands instead. -* More Info: https://docs.cypress.io/guides/references/migration-guide#-should -**/ -cy.should(($s) => { - cy.task(""); - }) - /** -* TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. -* You should use .then() to chain commands instead. -* More Info: https://docs.cypress.io/guides/references/migration-guide#-should -**/ -cy.should(function($el) { - cy.task(""); - }) - }) -}) -`; - shouldNotUseCyInShouldCB(tree, 'should-callback.ts'); - expect(tree.read('should-callback.ts', 'utf-8')).toEqual(expected); - shouldNotUseCyInShouldCB(tree, 'should-callback.ts'); - expect(tree.read('should-callback.ts', 'utf-8')).toEqual(expected); - }); - }); - describe('banned Cypres.Commands.overwrite', () => { - beforeEach(() => { - tree.write( - 'commands.ts', - `declare namespace Cypress { - interface Chainable { - login(email: string, password: string): void; - } -} -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -Cypress.Commands.overwrite('find', () => {}); -` - ); - }); - it('should comment', () => { - shouldNotOverrideCommands(tree, 'commands.ts'); - expect(tree.read('commands.ts', 'utf-8')).toMatchInlineSnapshot(` - "declare namespace Cypress { - interface Chainable { - login(email: string, password: string): void; - } - } - // - // -- This is a parent command -- - Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); - }); - /** - * TODO(@nrwl/cypress): This command can no longer be overridden - * Consider using a different name like 'custom_find' - * More info: https://docs.cypress.io/guides/references/migration-guide#Cypress-Commands-overwrite - **/ - Cypress.Commands.overwrite('find', () => {}); - " - `); - }); - - it('should be idempotent', () => { - const expected = `declare namespace Cypress { - interface Chainable { - login(email: string, password: string): void; - } -} -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -/** -* TODO(@nrwl/cypress): This command can no longer be overridden -* Consider using a different name like 'custom_find' -* More info: https://docs.cypress.io/guides/references/migration-guide#Cypress-Commands-overwrite -**/ -Cypress.Commands.overwrite('find', () => {}); -`; - - shouldNotOverrideCommands(tree, 'commands.ts'); - expect(tree.read('commands.ts', 'utf-8')).toEqual(expected); - shouldNotOverrideCommands(tree, 'commands.ts'); - expect(tree.read('commands.ts', 'utf-8')).toEqual(expected); - }); - }); - describe('api removal', () => { - it('should be idempotent', () => { - tree.write( - 'my-cool-test.cy.ts', - ` -describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - cy.server() - cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) -}) -` - ); - const expected = stripIndents`describe('something', () => { - it('should do the thing', () => { - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes - Cypress.Cookies.defaults() - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults - cy.server() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults - cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) - })`; - shouldUseCyIntercept(tree, 'my-cool-test.cy.ts'); - shouldUseCySession(tree, 'my-cool-test.cy.ts'); - expect(stripIndents`${tree.read('my-cool-test.cy.ts', 'utf-8')}`).toEqual( - expected - ); - - shouldUseCyIntercept(tree, 'my-cool-test.cy.ts'); - shouldUseCySession(tree, 'my-cool-test.cy.ts'); - expect(stripIndents`${tree.read('my-cool-test.cy.ts', 'utf-8')}`).toEqual( - expected - ); - }); - it('comment on cy.route,cy.server, & Cypress.Server.defaults usage', () => { - tree.write( - 'my-cool-test.cy.ts', - ` -describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - cy.server() - cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) -}) -` - ); - shouldUseCyIntercept(tree, 'my-cool-test.cy.ts'); - expect(tree.read('my-cool-test.cy.ts', 'utf-8')).toMatchInlineSnapshot(` - " - describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults - cy.server() - // TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults - cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) - }) - " - `); - }); - - it('comment on Cypress.Cookies.defaults & Cypress.Cookies.preserveOnce', () => { - tree.write( - 'my-cool-test.cy.ts', - ` -describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - cy.server() - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) -}) -` - ); - shouldUseCySession(tree, 'my-cool-test.cy.ts'); - expect(tree.read('my-cool-test.cy.ts', 'utf-8')).toMatchInlineSnapshot(` - " - describe('something', () => { - it('should do the thing', () => { - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes - Cypress.Cookies.defaults() - // TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - cy.server() - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) - }) - " - `); - }); - }); - describe('testIsolation', () => { - it('should be idempotent', () => { - const content = ` -import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - -export default defineConfig({ - e2e: { - ...nxE2EPreset(__filename), - testIsolation: true, -}) -`; - tree.write('my-cypress.config.ts', content); - turnOffTestIsolation(tree, 'my-cypress.config.ts'); - - expect(tree.read('my-cypress.config.ts', 'utf-8')).toEqual(content); - }); - it('should add testIsolation: false to the default e2e config', () => { - tree.write( - 'my-cypress.config.ts', - ` -import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - -export default defineConfig({ - e2e: nxE2EPreset(__filename), -}) -` - ); - turnOffTestIsolation(tree, 'my-cypress.config.ts'); - expect(tree.read('my-cypress.config.ts', 'utf-8')).toMatchInlineSnapshot(` - " - import { defineConfig } from 'cypress'; - import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - - export default defineConfig({ - e2e: { - ...nxE2EPreset(__filename), - /** - * TODO(@nrwl/cypress): In Cypress v12,the testIsolation option is turned on by default. - * This can cause tests to start breaking where not indended. - * You should consider enabling this once you verify tests do not depend on each other - * More Info: https://docs.cypress.io/guides/references/migration-guide#Test-Isolation - **/ - testIsolation: false, - }, - }) - " - `); - }); - - it('should add testIsolation: false to inline object e2e config', () => { - tree.write( - 'my-cypress.config.ts', - ` -import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - -export default defineConfig({ - e2e: { - ...nxE2EPreset(__filename), - video: false - } -}) -` - ); - turnOffTestIsolation(tree, 'my-cypress.config.ts'); - expect(tree.read('my-cypress.config.ts', 'utf-8')).toMatchInlineSnapshot(` - " - import { defineConfig } from 'cypress'; - import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - - export default defineConfig({ - e2e: { - ...nxE2EPreset(__filename), - video: false, - /** - * TODO(@nrwl/cypress): In Cypress v12,the testIsolation option is turned on by default. - * This can cause tests to start breaking where not indended. - * You should consider enabling this once you verify tests do not depend on each other - * More Info: https://docs.cypress.io/guides/references/migration-guide#Test-Isolation - **/ - testIsolation: false, - } - }) - " - `); - }); - - it('should add testIsolation: false for a variable e2e config', () => { - tree.write( - 'my-cypress.config.ts', - ` -import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; -const myConfig = { - ...nxE2EPreset(__filename), - video: false - } - -export default defineConfig({ - e2e: myConfig, -}) -` - ); - turnOffTestIsolation(tree, 'my-cypress.config.ts'); - expect(tree.read('my-cypress.config.ts', 'utf-8')).toMatchInlineSnapshot(` - " - import { defineConfig } from 'cypress'; - import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - const myConfig = { - ...nxE2EPreset(__filename), - video: false - } - - export default defineConfig({ - e2e: { - ...myConfig, - /** - * TODO(@nrwl/cypress): In Cypress v12,the testIsolation option is turned on by default. - * This can cause tests to start breaking where not indended. - * You should consider enabling this once you verify tests do not depend on each other - * More Info: https://docs.cypress.io/guides/references/migration-guide#Test-Isolation - **/ - testIsolation: false, - }, - }) - " - `); - }); - }); -}); - -function addCypressProject(tree: Tree, name: string) { - const targets = { - e2e: { - executor: '@nrwl/cypress:cypress', - options: { - tsConfig: `apps/${name}/tsconfig.e2e.json`, - testingType: 'e2e', - browser: 'chrome', - }, - configurations: { - dev: { - cypressConfig: `apps/${name}/cypress.config.ts`, - devServerTarget: 'client:serve:dev', - baseUrl: 'http://localhost:4206', - }, - watch: { - cypressConfig: 'apps/client-e2e/cypress-custom.config.ts', - devServerTarget: 'client:serve:watch', - baseUrl: 'http://localhost:4204', - }, - }, - defaultConfiguration: 'dev', - }, - }; - addProjectConfiguration(tree, name, { - root: `apps/${name}`, - sourceRoot: `apps/${name}/src`, - projectType: 'application', - targets, - }); - // testIsolation - tree.write( - `apps/${name}/cypress.config.ts`, - `import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - -export default defineConfig({ - e2e: nxE2EPreset(__filename) -})` - ); - // test Cypress.Commands.Override - tree.write( - `apps/${name}/src/support/commands.ts`, - `declare namespace Cypress { - interface Chainable { - login(email: string, password: string): void; - } -} -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -Cypress.Commands.overwrite('find', () => {}); -` - ); - // test .should(() => cy.) - tree.write( - `apps/${name}/src/e2e/callback.spec.ts`, - `describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - cy.server() - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - cy.should((b) => { - const a = 123; - // I'm not doing nested cy stuff - }); - cy.should(($s) => { - cy.task(""); - }) - cy.should(function($el) { - cy.task(""); - }) - }) -})` - ); - tree.write( - `apps/${name}/src/e2e/intercept-session.spec.ts`, - `describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - cy.server() - cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - }) -})` - ); - tree.write( - `apps/${name}/src/e2e/combo.spec.ts`, - `describe('something', () => { - it('should do the thing', () => { - Cypress.Cookies.defaults() - Cypress.Cookies.preserveOnce('seesion_id', 'remember-token'); - Cypress.blah.abc() - Cypress.Server.defaults({ - delay: 500, - method: 'GET', - }) - cy.server() - cy.route(/api/, () => { - return { - 'test': 'We’ll', - } - }).as('getApi') - - cy.visit('/index.html') - cy.window().then((win) => { - const xhr = new win.XMLHttpRequest - xhr.open('GET', '/api/v1/foo/bar?a=42') - xhr.send() - }) - - cy.wait('@getApi') - .its('url').should('include', 'api/v1') - cy.should(($s) => { - cy.get('@table').find('tr').should('have.length', 3) -}) - }) -})` - ); -} - -function assertMigration(tree: Tree, name: string) { - expect(tree.read(`apps/${name}/cypress.config.ts`, 'utf-8')).toContain( - 'testIsolation: false' - ); - // command overrides - expect(tree.read(`apps/${name}/src/support/commands.ts`, 'utf-8')).toContain( - 'TODO(@nrwl/cypress): This command can no longer be overridden' - ); - // test .should(() => cy.) - expect(tree.read(`apps/${name}/src/e2e/callback.spec.ts`, 'utf-8')).toContain( - 'TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws.' - ); - // use cy.intercept, cy.session - const interceptSessionSpec = tree.read( - `apps/${name}/src/e2e/intercept-session.spec.ts`, - 'utf-8' - ); - expect(interceptSessionSpec).toContain( - '// TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes' - ); - expect(interceptSessionSpec).toContain( - '// TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults' - ); - // intercept,session & callback - expect( - tree.read(`apps/${name}/src/e2e/combo.spec.ts`, 'utf-8') - ).toMatchSnapshot(); -} diff --git a/packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.ts b/packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.ts deleted file mode 100644 index 43344cdad578c..0000000000000 --- a/packages/cypress/src/migrations/update-15-5-0/update-to-cypress-12.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { - GeneratorCallback, - getProjects, - installPackagesTask, - stripIndents, - Tree, - updateJson, - visitNotIgnoredFiles, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { - CallExpression, - isArrowFunction, - isCallExpression, - isFunctionExpression, - isObjectLiteralExpression, - PropertyAccessExpression, - PropertyAssignment, -} from 'typescript'; -import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl'; -import { installedCypressVersion } from '../../utils/cypress-version'; -import { BANNED_COMMANDS, isAlreadyCommented } from './helpers'; - -const JS_TS_FILE_MATCHER = /\.[jt]sx?$/; - -export function updateToCypress12(tree: Tree): GeneratorCallback { - if (installedCypressVersion() < 11) { - return; - } - const projects = getProjects(tree); - - forEachExecutorOptions( - tree, - '@nrwl/cypress:cypress', - (options, projectName, targetName, configName) => { - if (!(options.cypressConfig && tree.exists(options.cypressConfig))) { - return; - } - const projectConfig = projects.get(projectName); - turnOffTestIsolation(tree, options.cypressConfig); - - visitNotIgnoredFiles(tree, projectConfig.root, (filePath) => { - if (!JS_TS_FILE_MATCHER.test(filePath)) { - return; - } - shouldUseCyIntercept(tree, filePath); - shouldUseCySession(tree, filePath); - shouldNotUseCyInShouldCB(tree, filePath); - shouldNotOverrideCommands(tree, filePath); - }); - } - ); - - console.warn(stripIndents`Cypress 12 has lots of breaking changes that might subtly break your tests. -This migration marked known issues that need to be manually migrated, -but there can still be runtime based errors that were not detected. -Please consult the offical Cypress v12 migration guide for more info on these changes and the next steps. -https://docs.cypress.io/guides/references/migration-guide - `); - - updateJson(tree, 'package.json', (json) => { - json.devDependencies.cypress = '^12.2.0'; - return json; - }); - - return () => { - installPackagesTask(tree); - }; -} - -export function turnOffTestIsolation(tree: Tree, configPath: string) { - const config = tree.read(configPath, 'utf-8'); - const isTestIsolationSet = tsquery.query( - config, - 'ExportAssignment ObjectLiteralExpression > PropertyAssignment:has(Identifier[name="testIsolation"])' - ); - - if (isTestIsolationSet.length > 0) { - return; - } - - const testIsolationProperty = `/** - * TODO(@nrwl/cypress): In Cypress v12,the testIsolation option is turned on by default. - * This can cause tests to start breaking where not indended. - * You should consider enabling this once you verify tests do not depend on each other - * More Info: https://docs.cypress.io/guides/references/migration-guide#Test-Isolation - **/ - testIsolation: false,`; - const updated = tsquery.replace( - config, - 'ExportAssignment ObjectLiteralExpression > PropertyAssignment:has(Identifier[name="e2e"])', - (node: PropertyAssignment) => { - if (isObjectLiteralExpression(node.initializer)) { - const listOfProperties = node.initializer.properties - .map((j) => j.getText()) - .join(',\n '); - return `e2e: { - ${listOfProperties}, - ${testIsolationProperty} - }`; - } - return `e2e: { - ...${node.initializer.getText()}, - ${testIsolationProperty} - }`; - } - ); - - tree.write(configPath, updated); -} - -/** - * Leave a comment on all apis that have been removed andsuperseded by cy.intercept - * stating they these API are now removed and need to update. - * cy.route, cy.server, Cypress.Server.defaults - **/ -export function shouldUseCyIntercept(tree: Tree, filePath: string) { - const content = tree.read(filePath, 'utf-8'); - const markedRemovedCommands = tsquery.replace( - content, - ':matches(PropertyAccessExpression:has(Identifier[name="cy"]):has(Identifier[name="server"], Identifier[name="route"]), PropertyAccessExpression:has(Identifier[name="defaults"]):has(Identifier[name="Cypress"], Identifier[name="Server"]))', - (node: PropertyAccessExpression) => { - if (isAlreadyCommented(node)) { - return; - } - const expression = node.expression.getText().trim(); - // prevent extra chaining i.e. cy.route().as() will return 2 results - // cy.route and cy.route().as - // only need the first 1 so skip any extra chaining - if (expression === 'cy' || expression === 'Cypress.Server') { - return `// TODO(@nrwl/cypress): this command has been removed, use cy.intercept instead. https://docs.cypress.io/guides/references/migration-guide#cy-server-cy-route-and-Cypress-Server-defaults -${node.getText()}`; - } - } - ); - - tree.write(filePath, markedRemovedCommands); -} - -/** - * Leave a comment on all apis that have been removed and superseded by cy.session - * stating they these API are now removed and need to update. - * Cypress.Cookies.defaults & Cypress.Cookies.preserveOnce - **/ -export function shouldUseCySession(tree: Tree, filePath: string) { - const content = tree.read(filePath, 'utf-8'); - const markedRemovedCommands = tsquery.replace( - content, - ':matches(PropertyAccessExpression:has(Identifier[name="defaults"]):has(Identifier[name="Cypress"], Identifier[name="Cookies"]), PropertyAccessExpression:has(Identifier[name="preserveOnce"]):has(Identifier[name="Cypress"], Identifier[name="Cookies"]))', - (node: PropertyAccessExpression) => { - if (isAlreadyCommented(node)) { - return; - } - const expression = node.expression.getText().trim(); - // prevent grabbing other Cypress..defaults - if (expression === 'Cypress.Cookies') { - return `// TODO(@nrwl/cypress): this command has been removed, use cy.session instead. https://docs.cypress.io/guides/references/migration-guide#Command-Cypress-API-Changes -${node.getText()}`; - } - } - ); - - tree.write(filePath, markedRemovedCommands); -} - -/** - * leave a comment about nested cy commands in a cy.should callback - * */ -export function shouldNotUseCyInShouldCB(tree: Tree, filePath: string) { - const content = tree.read(filePath, 'utf-8'); - const markedNestedCyCommands = tsquery.replace( - content, - 'CallExpression > PropertyAccessExpression:has(Identifier[name="cy"]):has(Identifier[name="should"])', - (node: PropertyAccessExpression) => { - if ( - isAlreadyCommented(node) || - (node.parent && !isCallExpression(node.parent)) - ) { - return; - } - const parentExpression = node.parent as CallExpression; - if ( - parentExpression?.arguments?.[0] && - (isArrowFunction(parentExpression.arguments[0]) || - isFunctionExpression(parentExpression.arguments[0])) - ) { - const isUsingNestedCyCommand = - tsquery.query( - parentExpression.arguments[0], - 'CallExpression > PropertyAccessExpression:has(Identifier[name="cy"])' - )?.length > 0; - if (isUsingNestedCyCommand) { - return `/** -* TODO(@nrwl/cypress): Nesting Cypress commands in a should assertion now throws. -* You should use .then() to chain commands instead. -* More Info: https://docs.cypress.io/guides/references/migration-guide#-should -**/ -${node.getText()}`; - } - return node.getText(); - } - } - ); - - tree.write(filePath, markedNestedCyCommands); -} - -/** - * leave a comment on all usages of overriding built-ins that are now banned - * */ -export function shouldNotOverrideCommands(tree: Tree, filePath: string) { - const content = tree.read(filePath, 'utf-8'); - const markedOverrideUsage = tsquery.replace( - content, - 'PropertyAccessExpression:has(Identifier[name="overwrite"]):has(Identifier[name="Cypress"])', - (node: PropertyAccessExpression) => { - if (isAlreadyCommented(node)) { - return; - } - const expression = node.expression.getText().trim(); - // prevent grabbing other Cypress..defaults - - if (expression === 'Cypress.Commands') { - // get value. - const overwriteExpression = node.parent as CallExpression; - - const command = (overwriteExpression.arguments?.[0] as any)?.text; // need string without quotes - if (BANNED_COMMANDS.includes(command)) { - // overwrite - return `/** -* TODO(@nrwl/cypress): This command can no longer be overridden -* Consider using a different name like 'custom_${command}' -* More info: https://docs.cypress.io/guides/references/migration-guide#Cypress-Commands-overwrite -**/ -${node.getText()}`; - } - } - } - ); - - tree.write(filePath, markedOverrideUsage); -} - -export default updateToCypress12; diff --git a/packages/detox/migrations.json b/packages/detox/migrations.json index 07f474d24bbc3..aa9b8dd485816 100644 --- a/packages/detox/migrations.json +++ b/packages/detox/migrations.json @@ -20,42 +20,6 @@ } }, "packageJsonUpdates": { - "15.0.0": { - "version": "15.0.0-beta.0", - "packages": { - "detox": { - "version": "19.12.5", - "alwaysAddToPackageJson": false - } - } - }, - "15.2.2": { - "version": "15.2.2-beta.0", - "packages": { - "detox": { - "version": "20.0.3", - "alwaysAddToPackageJson": false - } - } - }, - "15.6.2": { - "version": "15.6.2-beta.0", - "packages": { - "detox": { - "version": "20.1.1", - "alwaysAddToPackageJson": false - } - } - }, - "15.8.6": { - "version": "15.8.6-beta.0", - "packages": { - "detox": { - "version": "~20.5.0", - "alwaysAddToPackageJson": false - } - } - }, "16.0.0": { "version": "16.0.0-beta.3", "packages": { diff --git a/packages/devkit/.eslintrc.json b/packages/devkit/.eslintrc.json index 29aa362d1c72b..bb38a04b355dd 100644 --- a/packages/devkit/.eslintrc.json +++ b/packages/devkit/.eslintrc.json @@ -17,9 +17,15 @@ ], "patterns": [ { - "group": ["nx/**/*"], - "message": "Use requireNx() from packages/devkit/nx.ts OR use a type import instead.", - "allowTypeImports": true + "group": [ + "nx/bin/*", + "nx/src/*", + "nx/plugins/*", + "!nx/src/devkit-internals", + "!nx/src/devkit-exports" + ], + "allowTypeImports": true, + "message": "Only import from nx/src/devkit-internals or nx/src/devkit-exports" }, { "group": ["@nx/devkit/**/*"], diff --git a/packages/devkit/nx.ts b/packages/devkit/nx.ts deleted file mode 100644 index 88089dd4943aa..0000000000000 --- a/packages/devkit/nx.ts +++ /dev/null @@ -1,15 +0,0 @@ -// After Nx v19, this can be removed and replaced with either: -// - import {} from 'nx/src/devkit-exports' -// - import {} from 'nx/src/devkit-internals' -export function requireNx(): typeof import('nx/src/devkit-exports') & - Partial { - let result = { ...require('nx/src/devkit-exports') }; - try { - result = { - ...result, - // Remove in Nx v19, devkit should not support Nx v16.0.2 at that point. - ...require('nx/src/devkit-internals'), - }; - } catch {} - return result; -} diff --git a/packages/devkit/package.json b/packages/devkit/package.json index 133b83cbc947f..b40a777f6a381 100644 --- a/packages/devkit/package.json +++ b/packages/devkit/package.json @@ -38,7 +38,7 @@ "minimatch": "9.0.3" }, "peerDependencies": { - "nx": ">= 16 <= 19" + "nx": ">= 17 <= 20" }, "publishConfig": { "access": "public" diff --git a/packages/devkit/src/executors/parse-target-string.ts b/packages/devkit/src/executors/parse-target-string.ts index 0bbc33278f80e..aab8bba679dbb 100644 --- a/packages/devkit/src/executors/parse-target-string.ts +++ b/packages/devkit/src/executors/parse-target-string.ts @@ -1,15 +1,10 @@ -import type { Target } from 'nx/src/command-line/run/run'; -import type { ProjectGraph } from 'nx/src/config/project-graph'; -import type { ExecutorContext } from 'nx/src/devkit-exports'; - -import { requireNx } from '../../nx'; - -let { readCachedProjectGraph, splitTarget, splitByColons } = requireNx(); - -// TODO: Remove this in Nx 19 when Nx 16.7.0 is no longer supported -splitTarget = splitTarget ?? require('nx/src/utils/split-target').splitTarget; -splitByColons = - splitByColons ?? ((s: string) => s.split(':') as [string, ...string[]]); +import { + ExecutorContext, + ProjectGraph, + readCachedProjectGraph, + Target, +} from 'nx/src/devkit-exports'; +import { splitByColons, splitTarget } from 'nx/src/devkit-internals'; /** * @deprecated(v17) A project graph should be passed to parseTargetString for best accuracy. diff --git a/packages/devkit/src/executors/read-target-options.ts b/packages/devkit/src/executors/read-target-options.ts index b0180bf47193c..ae80d2d96a461 100644 --- a/packages/devkit/src/executors/read-target-options.ts +++ b/packages/devkit/src/executors/read-target-options.ts @@ -1,19 +1,12 @@ -import type { Target } from 'nx/src/command-line/run/run'; -import type { ExecutorContext } from 'nx/src/config/misc-interfaces'; -import { requireNx } from '../../nx'; import { relative } from 'path'; -let { - Workspaces, - getExecutorInformation, +import type { ExecutorContext, Target } from 'nx/src/devkit-exports'; + +import { calculateDefaultProjectName, combineOptionsForExecutor, -} = requireNx(); - -// TODO: Remove this in Nx 19 when Nx 16.7.0 is no longer supported -combineOptionsForExecutor = - combineOptionsForExecutor ?? - require('nx/src/utils/params').combineOptionsForExecutor; + getExecutorInformation, +} from 'nx/src/devkit-internals'; /** * Reads and combines options for a given target. @@ -38,32 +31,20 @@ export function readTargetOptions( throw new Error(`Unable to find target ${target} for project ${project}`); } - // TODO(v19): remove Workspaces. - const ws = new Workspaces(context.root); const [nodeModule, executorName] = targetConfiguration.executor.split(':'); - const { schema } = getExecutorInformation - ? getExecutorInformation( - nodeModule, - executorName, - context.root, - context.projectsConfigurations?.projects ?? context.workspace.projects - ) - : // TODO(v19): remove readExecutor. This is to be backwards compatible with Nx 16.5 and below. - (ws as any).readExecutor(nodeModule, executorName); - - const defaultProject = calculateDefaultProjectName - ? calculateDefaultProjectName( - context.cwd, - context.root, - { version: 2, projects: context.projectsConfigurations.projects }, - context.nxJsonConfiguration - ) - : // TODO(v19): remove calculateDefaultProjectName. This is to be backwards compatible with Nx 16.5 and below. - (ws as any).calculateDefaultProjectName( - context.cwd, - { version: 2, projects: context.projectsConfigurations.projects }, - context.nxJsonConfiguration - ); + const { schema } = getExecutorInformation( + nodeModule, + executorName, + context.root, + context.projectsConfigurations?.projects ?? context.workspace.projects + ); + + const defaultProject = calculateDefaultProjectName( + context.cwd, + context.root, + { version: 2, projects: context.projectsConfigurations.projects }, + context.nxJsonConfiguration + ); return combineOptionsForExecutor( {}, diff --git a/packages/devkit/src/generators/add-build-target-defaults.ts b/packages/devkit/src/generators/add-build-target-defaults.ts index 7162ad507c1c7..6158f6e3b8cd1 100644 --- a/packages/devkit/src/generators/add-build-target-defaults.ts +++ b/packages/devkit/src/generators/add-build-target-defaults.ts @@ -1,7 +1,4 @@ -import type { Tree } from 'nx/src/devkit-exports'; -import { requireNx } from '../../nx'; - -const { readNxJson, updateNxJson } = requireNx(); +import { readNxJson, Tree, updateNxJson } from 'nx/src/devkit-exports'; export function addBuildTargetDefaults( tree: Tree, diff --git a/packages/devkit/src/generators/artifact-name-and-directory-utils.ts b/packages/devkit/src/generators/artifact-name-and-directory-utils.ts index 9856ed4cee9b4..a3e6f20054c27 100644 --- a/packages/devkit/src/generators/artifact-name-and-directory-utils.ts +++ b/packages/devkit/src/generators/artifact-name-and-directory-utils.ts @@ -1,20 +1,22 @@ import { prompt } from 'enquirer'; -import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import type { Tree } from 'nx/src/generators/tree'; import { join, relative } from 'path'; -import { requireNx } from '../../nx'; import { names } from '../utils/names'; -const { - createProjectRootMappingsFromProjectConfigurations, - findProjectForPath, +import { getProjects, joinPathFragments, logger, normalizePath, output, + ProjectConfiguration, + Tree, workspaceRoot, -} = requireNx(); +} from 'nx/src/devkit-exports'; + +import { + createProjectRootMappingsFromProjectConfigurations, + findProjectForPath, +} from 'nx/src/devkit-internals'; export type NameAndDirectoryFormat = 'as-provided' | 'derived'; export type ArtifactGenerationOptions = { @@ -142,7 +144,7 @@ function logDeprecationMessage( formats: NameAndDirectoryFormats ) { logger.warn(` -In Nx 19, generating a ${options.artifactType} will no longer support providing a project and deriving the directory. +In Nx 20, generating a ${options.artifactType} will no longer support providing a project and deriving the directory. Please provide the exact directory in the future. Example: nx g ${options.callingGenerator} ${formats['derived'].artifactName} --directory ${formats['derived'].directory} NOTE: The example above assumes the command is being run from the workspace root. If the command is being run from a subdirectory, the directory option should be adjusted accordingly. diff --git a/packages/devkit/src/generators/executor-options-utils.ts b/packages/devkit/src/generators/executor-options-utils.ts index 0f26036804292..9a65203e3d7e2 100644 --- a/packages/devkit/src/generators/executor-options-utils.ts +++ b/packages/devkit/src/generators/executor-options-utils.ts @@ -1,9 +1,9 @@ -import type { Tree } from 'nx/src/generators/tree'; -import type { ProjectGraph } from 'nx/src/config/project-graph'; -import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import { requireNx } from '../../nx'; - -const { getProjects } = requireNx(); +import { + getProjects, + ProjectConfiguration, + ProjectGraph, + Tree, +} from 'nx/src/devkit-exports'; type CallBack = ( currentValue: T, diff --git a/packages/devkit/src/generators/format-files.ts b/packages/devkit/src/generators/format-files.ts index e4d616b1dd415..63a786c7c0676 100644 --- a/packages/devkit/src/generators/format-files.ts +++ b/packages/devkit/src/generators/format-files.ts @@ -1,13 +1,8 @@ -import type { Tree } from 'nx/src/generators/tree'; import * as path from 'path'; import type * as Prettier from 'prettier'; -import { requireNx } from '../../nx'; -let { updateJson, readJson, sortObjectByKeys } = requireNx(); - -// TODO: Remove this in Nx 19 when Nx 16.7.0 is no longer supported -sortObjectByKeys = - sortObjectByKeys ?? require('nx/src/utils/object-sort').sortObjectByKeys; +import { readJson, Tree, updateJson } from 'nx/src/devkit-exports'; +import { sortObjectByKeys } from 'nx/src/devkit-internals'; /** * Formats all the created or updated files using Prettier diff --git a/packages/devkit/src/generators/generate-files.ts b/packages/devkit/src/generators/generate-files.ts index ff2d2c448fa00..1cef0e1ba57cb 100644 --- a/packages/devkit/src/generators/generate-files.ts +++ b/packages/devkit/src/generators/generate-files.ts @@ -1,10 +1,8 @@ -import { readFileSync, readdirSync, statSync } from 'fs'; +import { readdirSync, readFileSync, statSync } from 'fs'; import * as path from 'path'; -import type { Tree } from 'nx/src/generators/tree'; -import { requireNx } from '../../nx'; import { isBinaryPath } from '../utils/binary-extensions'; -const { logger } = requireNx(); +import { logger, Tree } from 'nx/src/devkit-exports'; /** * Generates a folder of files based on provided templates. diff --git a/packages/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator.ts b/packages/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator.ts index 113b49da14aa5..94128583562fb 100644 --- a/packages/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator.ts +++ b/packages/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator.ts @@ -1,34 +1,30 @@ -import type { TargetConfiguration } from 'nx/src/config/workspace-json-project-json'; -import type { - ExpandedPluginConfiguration, - NxJsonConfiguration, -} from 'nx/src/config/nx-json'; -import type { Tree } from 'nx/src/generators/tree'; -import type { - CreateNodes, - CreateNodesContext, -} from 'nx/src/project-graph/plugins'; -import type { ProjectGraph } from 'nx/src/config/project-graph'; import type { RunCommandsOptions } from 'nx/src/executors/run-commands/run-commands.impl'; -import type { ConfigurationResult } from 'nx/src/project-graph/utils/project-configuration-utils'; import { minimatch } from 'minimatch'; import { forEachExecutorOptions } from '../executor-options-utils'; import { deleteMatchingProperties } from './plugin-migration-utils'; -import { requireNx } from '../../../nx'; -const { - glob, +import { readNxJson, updateNxJson, - mergeTargetConfigurations, updateProjectConfiguration, readProjectConfiguration, + ProjectGraph, + ExpandedPluginConfiguration, + NxJsonConfiguration, + TargetConfiguration, + Tree, + CreateNodes, +} from 'nx/src/devkit-exports'; + +import { + mergeTargetConfigurations, retrieveProjectConfigurations, LoadedNxPlugin, ProjectConfigurationsError, -} = requireNx(); +} from 'nx/src/devkit-internals'; +import type { ConfigurationResult } from 'nx/src/project-graph/utils/project-configuration-utils'; type PluginOptionsBuilder = (targetName: string) => T; type PostTargetTransformer = ( diff --git a/packages/devkit/src/generators/project-name-and-root-utils.ts b/packages/devkit/src/generators/project-name-and-root-utils.ts index cd4959f2b64fe..48538953475e0 100644 --- a/packages/devkit/src/generators/project-name-and-root-utils.ts +++ b/packages/devkit/src/generators/project-name-and-root-utils.ts @@ -1,23 +1,22 @@ import { prompt } from 'enquirer'; -import type { ProjectType } from 'nx/src/config/workspace-json-project-json'; -import type { Tree } from 'nx/src/generators/tree'; import { join, relative } from 'path'; -import { requireNx } from '../../nx'; import { extractLayoutDirectory, getWorkspaceLayout, } from '../utils/get-workspace-layout'; import { names } from '../utils/names'; -const { +import { joinPathFragments, logger, normalizePath, output, + ProjectType, readJson, stripIndents, + Tree, workspaceRoot, -} = requireNx(); +} from 'nx/src/devkit-exports'; export type ProjectNameAndRootFormat = 'as-provided' | 'derived'; export type ProjectGenerationOptions = { @@ -130,7 +129,7 @@ function logDeprecationMessage( formats: ProjectNameAndRootFormats ) { logger.warn(stripIndents` - In Nx 19, generating projects will no longer derive the name and root. + In Nx 20, generating projects will no longer derive the name and root. Please provide the exact project name and root in the future. Example: nx g ${callingGenerator} ${formats['derived'].projectName} --directory ${formats['derived'].projectRoot} `); diff --git a/packages/devkit/src/generators/run-tasks-in-serial.ts b/packages/devkit/src/generators/run-tasks-in-serial.ts index a6ff55767ff21..85d28a084a74f 100644 --- a/packages/devkit/src/generators/run-tasks-in-serial.ts +++ b/packages/devkit/src/generators/run-tasks-in-serial.ts @@ -1,4 +1,4 @@ -import type { GeneratorCallback } from 'nx/src/config/misc-interfaces'; +import type { GeneratorCallback } from 'nx/src/devkit-exports'; /** * Run tasks in serial diff --git a/packages/devkit/src/generators/to-js.ts b/packages/devkit/src/generators/to-js.ts index 0a4f30bc21465..cba3f61b4e8bd 100644 --- a/packages/devkit/src/generators/to-js.ts +++ b/packages/devkit/src/generators/to-js.ts @@ -1,4 +1,4 @@ -import type { Tree } from 'nx/src/generators/tree'; +import type { Tree } from 'nx/src/devkit-exports'; import type { ScriptTarget, ModuleKind } from 'typescript'; import { typescriptVersion } from '../utils/versions'; import { ensurePackage } from '../utils/package-json'; diff --git a/packages/devkit/src/generators/update-ts-configs-to-js.ts b/packages/devkit/src/generators/update-ts-configs-to-js.ts index a61b3669615cc..98b56d70fb0c3 100644 --- a/packages/devkit/src/generators/update-ts-configs-to-js.ts +++ b/packages/devkit/src/generators/update-ts-configs-to-js.ts @@ -1,7 +1,4 @@ -import type { Tree } from 'nx/src/generators/tree'; -import { requireNx } from '../../nx'; - -const { updateJson } = requireNx(); +import { Tree, updateJson } from 'nx/src/devkit-exports'; export function updateTsConfigsToJs( tree: Tree, diff --git a/packages/devkit/src/generators/visit-not-ignored-files.ts b/packages/devkit/src/generators/visit-not-ignored-files.ts index 87a6ea0b7ebce..16d94f067c2b7 100644 --- a/packages/devkit/src/generators/visit-not-ignored-files.ts +++ b/packages/devkit/src/generators/visit-not-ignored-files.ts @@ -1,4 +1,4 @@ -import type { Tree } from 'nx/src/generators/tree'; +import type { Tree } from 'nx/src/devkit-exports'; import ignore from 'ignore'; import { join, relative, sep } from 'path'; diff --git a/packages/devkit/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.ts b/packages/devkit/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.ts index 625e9ab430293..6a74372f31a65 100644 --- a/packages/devkit/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.ts +++ b/packages/devkit/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.ts @@ -1,4 +1,4 @@ -import type { Tree } from 'nx/src/generators/tree'; +import type { Tree } from 'nx/src/devkit-exports'; import { formatFiles } from '../../generators/format-files'; import { replaceNrwlPackageWithNxPackage } from '../../utils/replace-package'; diff --git a/packages/devkit/src/migrations/update-16-9-0/migrate-mf-util-usage.ts b/packages/devkit/src/migrations/update-16-9-0/migrate-mf-util-usage.ts index 3a0db4656a758..ec28fd5516772 100644 --- a/packages/devkit/src/migrations/update-16-9-0/migrate-mf-util-usage.ts +++ b/packages/devkit/src/migrations/update-16-9-0/migrate-mf-util-usage.ts @@ -1,16 +1,13 @@ -import type { Tree } from 'nx/src/generators/tree'; -import type { GeneratorCallback } from 'nx/src/config/misc-interfaces'; import type { Node, SyntaxKind } from 'typescript'; import { visitNotIgnoredFiles } from '../../generators/visit-not-ignored-files'; import { formatFiles } from '../../generators/format-files'; -import { requireNx } from '../../../nx'; import { addDependenciesToPackageJson, ensurePackage, } from '../../utils/package-json'; import { typescriptVersion } from '../../utils/versions'; -const { readJson } = requireNx(); +import { GeneratorCallback, readJson, Tree } from 'nx/src/devkit-exports'; let tsModule: typeof import('typescript'); diff --git a/packages/devkit/src/tasks/install-packages-task.ts b/packages/devkit/src/tasks/install-packages-task.ts index 64dbc5a46fbb7..a9d4bc78cf9ff 100644 --- a/packages/devkit/src/tasks/install-packages-task.ts +++ b/packages/devkit/src/tasks/install-packages-task.ts @@ -1,11 +1,13 @@ -import { type ExecSyncOptions, execSync } from 'child_process'; +import { execSync, type ExecSyncOptions } from 'child_process'; import { join } from 'path'; -import { requireNx } from '../../nx'; -import type { Tree } from 'nx/src/generators/tree'; -import type { PackageManager } from 'nx/src/utils/package-manager'; -const { detectPackageManager, getPackageManagerCommand, joinPathFragments } = - requireNx(); +import { + detectPackageManager, + getPackageManagerCommand, + joinPathFragments, + PackageManager, + Tree, +} from 'nx/src/devkit-exports'; /** * Runs `npm install` or `yarn install`. It will skip running the install if diff --git a/packages/devkit/src/utils/add-plugin.ts b/packages/devkit/src/utils/add-plugin.ts index 1a4a87fadc968..79fcf70e0743b 100644 --- a/packages/devkit/src/utils/add-plugin.ts +++ b/packages/devkit/src/utils/add-plugin.ts @@ -1,24 +1,23 @@ -import { - type CreateNodes, - type ProjectConfiguration, - type ProjectGraph, - type Tree, -} from 'nx/src/devkit-exports'; import type { PackageJson } from 'nx/src/utils/package-json'; + +import type { ConfigurationResult } from 'nx/src/project-graph/utils/project-configuration-utils'; import * as yargs from 'yargs-parser'; -import { requireNx } from '../../nx'; -const { +import { + CreateNodes, + ProjectConfiguration, + ProjectGraph, readJson, - writeJson, readNxJson, + Tree, updateNxJson, - retrieveProjectConfigurations, + writeJson, +} from 'nx/src/devkit-exports'; +import { LoadedNxPlugin, ProjectConfigurationsError, -} = requireNx(); - -import type { ConfigurationResult } from 'nx/src/project-graph/utils/project-configuration-utils'; + retrieveProjectConfigurations, +} from 'nx/src/devkit-internals'; /** * Iterates through various forms of plugin options to find the one which does not conflict with the current graph diff --git a/packages/devkit/src/utils/calculate-hash-for-create-nodes.ts b/packages/devkit/src/utils/calculate-hash-for-create-nodes.ts index d1235a42c4ca1..641bc52bbd4c2 100644 --- a/packages/devkit/src/utils/calculate-hash-for-create-nodes.ts +++ b/packages/devkit/src/utils/calculate-hash-for-create-nodes.ts @@ -1,7 +1,7 @@ -import type { CreateNodesContext } from 'nx/src/devkit-exports'; -import { requireNx } from '../../nx'; import { join } from 'path'; -const { hashWithWorkspaceContext, hashArray, hashObject } = requireNx(); +import { CreateNodesContext, hashArray } from 'nx/src/devkit-exports'; + +import { hashObject, hashWithWorkspaceContext } from 'nx/src/devkit-internals'; export function calculateHashForCreateNodes( projectRoot: string, diff --git a/packages/devkit/src/utils/config-utils.ts b/packages/devkit/src/utils/config-utils.ts index fdee82126b8c1..8ee479c06dd4c 100644 --- a/packages/devkit/src/utils/config-utils.ts +++ b/packages/devkit/src/utils/config-utils.ts @@ -1,9 +1,8 @@ import { dirname, extname, join, sep } from 'path'; import { existsSync, readdirSync } from 'fs'; -import { requireNx } from '../../nx'; import { pathToFileURL } from 'node:url'; - -const { workspaceRoot, registerTsProject } = requireNx(); +import { workspaceRoot } from 'nx/src/devkit-exports'; +import { registerTsProject } from 'nx/src/devkit-internals'; export let dynamicImport = new Function( 'modulePath', diff --git a/packages/devkit/src/utils/convert-nx-executor.ts b/packages/devkit/src/utils/convert-nx-executor.ts index 242cdef0e00a4..446f0d6409657 100644 --- a/packages/devkit/src/utils/convert-nx-executor.ts +++ b/packages/devkit/src/utils/convert-nx-executor.ts @@ -1,17 +1,17 @@ import type { Observable } from 'rxjs'; -import type { Executor, ExecutorContext } from 'nx/src/config/misc-interfaces'; -import type { ProjectsConfigurations } from 'nx/src/devkit-exports'; +import type { + Executor, + ExecutorContext, + ProjectsConfigurations, +} from 'nx/src/devkit-exports'; -import { requireNx } from '../../nx'; import { NX_VERSION } from './package-json'; import { lt } from 'semver'; - -const { - Workspaces, +import { readNxJsonFromDisk, - retrieveProjectConfigurationsWithAngularProjects, readProjectConfigurationsFromRootMap, -} = requireNx(); + retrieveProjectConfigurationsWithAngularProjects, +} from 'nx/src/devkit-internals'; /** * Convert an Nx Executor into an Angular Devkit Builder @@ -21,43 +21,35 @@ const { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function convertNxExecutor(executor: Executor) { const builderFunction = (options, builderContext) => { - const workspaces = new Workspaces(builderContext.workspaceRoot); - const nxJsonConfiguration = readNxJsonFromDisk - ? readNxJsonFromDisk(builderContext.workspaceRoot) - : // TODO(v19): remove readNxJson. This is to be backwards compatible with Nx 16.5 and below. - (workspaces as any).readNxJson(); + const nxJsonConfiguration = readNxJsonFromDisk( + builderContext.workspaceRoot + ); const promise = async () => { - const projectsConfigurations: ProjectsConfigurations = - retrieveProjectConfigurationsWithAngularProjects - ? { - version: 2, - projects: await retrieveProjectConfigurationsWithAngularProjects( - builderContext.workspaceRoot, - nxJsonConfiguration - ).then((p) => { - if ((p as any).projectNodes) { - return (p as any).projectNodes; - } - // v18.3.4 changed projects to be keyed by root - // rather than project name - if (lt(NX_VERSION, '18.3.4')) { - return p.projects; - } + const projectsConfigurations: ProjectsConfigurations = { + version: 2, + projects: await retrieveProjectConfigurationsWithAngularProjects( + builderContext.workspaceRoot, + nxJsonConfiguration + ).then((p) => { + if ((p as any).projectNodes) { + return (p as any).projectNodes; + } + // v18.3.4 changed projects to be keyed by root + // rather than project name + if (lt(NX_VERSION, '18.3.4')) { + return p.projects; + } - if (readProjectConfigurationsFromRootMap) { - return readProjectConfigurationsFromRootMap(p.projects); - } + if (readProjectConfigurationsFromRootMap) { + return readProjectConfigurationsFromRootMap(p.projects); + } - throw new Error( - 'Unable to successfully map Nx executor -> Angular Builder' - ); - }), - } - : // TODO(v19): remove retrieveProjectConfigurations. This is to be backwards compatible with Nx 16.5 and below. - (workspaces as any).readProjectsConfigurations({ - _includeProjectsFromAngularJson: true, - }); + throw new Error( + 'Unable to successfully map Nx executor -> Angular Builder' + ); + }), + }; const context: ExecutorContext = { root: builderContext.workspaceRoot, diff --git a/packages/devkit/src/utils/get-named-inputs.ts b/packages/devkit/src/utils/get-named-inputs.ts index 59b2a916efa24..e9d5ba0bdfec2 100644 --- a/packages/devkit/src/utils/get-named-inputs.ts +++ b/packages/devkit/src/utils/get-named-inputs.ts @@ -1,15 +1,14 @@ import { join } from 'path'; import { existsSync } from 'fs'; -import type { - CreateNodesContext, - ProjectConfiguration, -} from 'nx/src/devkit-exports'; import type { PackageJson } from 'nx/src/utils/package-json'; import type { InputDefinition } from 'nx/src/config/workspace-json-project-json'; -import { requireNx } from '../../nx'; -const { readJsonFile } = requireNx(); +import { + CreateNodesContext, + ProjectConfiguration, + readJsonFile, +} from 'nx/src/devkit-exports'; /** * Get the named inputs available for a directory diff --git a/packages/devkit/src/utils/get-workspace-layout.ts b/packages/devkit/src/utils/get-workspace-layout.ts index 4bb41e3ce6519..e6e9c6aa4bc0f 100644 --- a/packages/devkit/src/utils/get-workspace-layout.ts +++ b/packages/devkit/src/utils/get-workspace-layout.ts @@ -1,7 +1,4 @@ -import type { Tree } from 'nx/src/generators/tree'; -import { requireNx } from '../../nx'; - -const { readNxJson } = requireNx(); +import { readNxJson, Tree } from 'nx/src/devkit-exports'; /** * Returns workspace defaults. It includes defaults folders for apps and libs, diff --git a/packages/devkit/src/utils/invoke-nx-generator.ts b/packages/devkit/src/utils/invoke-nx-generator.ts index c158a71c87649..23ec202ede05f 100644 --- a/packages/devkit/src/utils/invoke-nx-generator.ts +++ b/packages/devkit/src/utils/invoke-nx-generator.ts @@ -1,20 +1,14 @@ -import type { +import { join, relative } from 'path'; +import type { Mode } from 'fs'; +import type { TreeWriteOptions } from 'nx/src/generators/tree'; +import { FileChange, - Tree, - TreeWriteOptions, -} from 'nx/src/generators/tree'; -import type { Generator, GeneratorCallback, -} from 'nx/src/config/misc-interfaces'; -import { join, relative } from 'path'; -import type { Mode } from 'fs'; -import { requireNx } from '../../nx'; - -let { logger, stripIndent } = requireNx(); - -// TODO: Remove this in Nx 19 when Nx 16.7.0 is no longer supported -stripIndent = stripIndent ?? require('nx/src/utils/logger').stripIndent; + logger, + Tree, +} from 'nx/src/devkit-exports'; +import { stripIndent } from 'nx/src/devkit-internals'; class RunCallbackTask { constructor(private callback: GeneratorCallback) {} diff --git a/packages/devkit/src/utils/log-show-project-command.ts b/packages/devkit/src/utils/log-show-project-command.ts index d085ea74fc1fc..8101bcdaf4730 100644 --- a/packages/devkit/src/utils/log-show-project-command.ts +++ b/packages/devkit/src/utils/log-show-project-command.ts @@ -1,7 +1,6 @@ -import { requireNx } from '../../nx'; +import { output } from 'nx/src/devkit-exports'; export function logShowProjectCommand(projectName: string): void { - const { output } = requireNx(); output.log({ title: `👀 View Details of ${projectName}`, bodyLines: [ diff --git a/packages/devkit/src/utils/move-dir.ts b/packages/devkit/src/utils/move-dir.ts index 0ff349b169c34..405adf1b9442f 100644 --- a/packages/devkit/src/utils/move-dir.ts +++ b/packages/devkit/src/utils/move-dir.ts @@ -1,9 +1,8 @@ -import type { Tree } from 'nx/src/generators/tree'; import { relative } from 'path'; import { visitNotIgnoredFiles } from '../generators/visit-not-ignored-files'; -import { requireNx } from '../../nx'; -const { normalizePath } = requireNx(); +import { normalizePath, Tree } from 'nx/src/devkit-exports'; + /** * Analogous to cp -r oldDir newDir */ diff --git a/packages/devkit/src/utils/package-json.ts b/packages/devkit/src/utils/package-json.ts index 12b8430170a14..ac0fee718b477 100644 --- a/packages/devkit/src/utils/package-json.ts +++ b/packages/devkit/src/utils/package-json.ts @@ -1,27 +1,23 @@ import { execSync } from 'child_process'; import { Module } from 'module'; - -import type { Tree } from 'nx/src/generators/tree'; - -import type { GeneratorCallback } from 'nx/src/config/misc-interfaces'; import { clean, coerce, gt } from 'semver'; import { installPackagesTask } from '../tasks/install-packages-task'; -import { requireNx } from '../../nx'; import { dirSync } from 'tmp'; import { join } from 'path'; -import type { PackageManager } from 'nx/src/utils/package-manager'; -import { writeFileSync } from 'fs'; - -const { +import { + detectPackageManager, + GeneratorCallback, + getPackageManagerCommand, + getPackageManagerVersion, + PackageManager, readJson, + Tree, updateJson, - getPackageManagerCommand, workspaceRoot, - detectPackageManager, - createTempNpmDirectory, - getPackageManagerVersion, -} = requireNx(); +} from 'nx/src/devkit-exports'; +import { createTempNpmDirectory } from 'nx/src/devkit-internals'; +import { writeFileSync } from 'fs'; const UNIDENTIFIED_VERSION = 'UNIDENTIFIED_VERSION'; const NON_SEMVER_TAGS = { diff --git a/packages/devkit/src/utils/replace-package.ts b/packages/devkit/src/utils/replace-package.ts index 2340dde471128..5871fed491b2b 100644 --- a/packages/devkit/src/utils/replace-package.ts +++ b/packages/devkit/src/utils/replace-package.ts @@ -1,18 +1,16 @@ -import type { Tree } from 'nx/src/generators/tree'; +import { + getProjects, + logger, + readNxJson, + Tree, + updateJson, + updateNxJson, + updateProjectConfiguration, +} from 'nx/src/devkit-exports'; import type { PackageJson } from 'nx/src/utils/package-json'; -import { requireNx } from '../../nx'; import { visitNotIgnoredFiles } from '../generators/visit-not-ignored-files'; import { basename } from 'path'; import { isBinaryPath } from './binary-extensions'; -const { logger } = requireNx(); - -const { - getProjects, - updateProjectConfiguration, - readNxJson, - updateNxJson, - updateJson, -} = requireNx(); export function replaceNrwlPackageWithNxPackage( tree: Tree, diff --git a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts index c018bafd01b9e..522965224f0f9 100644 --- a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts +++ b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts @@ -1,19 +1,15 @@ -import type { - Tree, +import { CreateNodes, + glob, ProjectConfiguration, - TargetConfiguration, -} from 'nx/src/devkit-exports'; -import { requireNx } from '../../nx'; -const { readNxJson, - updateNxJson, - glob, - hashObject, - findProjectForPath, readProjectConfiguration, + TargetConfiguration, + Tree, + updateNxJson, updateProjectConfiguration, -} = requireNx(); +} from 'nx/src/devkit-exports'; +import { findProjectForPath, hashObject } from 'nx/src/devkit-internals'; export async function replaceProjectConfigurationsWithPlugin( tree: Tree, diff --git a/packages/esbuild/migrations.json b/packages/esbuild/migrations.json index 9889e30ba718c..722387067d0aa 100644 --- a/packages/esbuild/migrations.json +++ b/packages/esbuild/migrations.json @@ -1,11 +1,5 @@ { "generators": { - "set-generate-package-json": { - "cli": "nx", - "version": "15.8.7-beta.0", - "description": "Set generatePackageJson to true to maintain existing behavior of generating package.json in output path.", - "factory": "./src/migrations/update-15-8-7/set-generate-package-json" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -20,15 +14,6 @@ } }, "packageJsonUpdates": { - "15.7.0": { - "version": "15.7.0-beta.0", - "packages": { - "esbuild": { - "version": "0.17.5", - "alwaysAddToPackageJson": false - } - } - }, "16.0.0": { "version": "16.0.0-beta.5", "packages": { diff --git a/packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.spec.ts b/packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.spec.ts deleted file mode 100644 index b4b80472ce63c..0000000000000 --- a/packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import update from './set-generate-package-json'; - -describe('Migration: Set generatePackageJson', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace(); - }); - - it('should keep existing generatePackageJson option if it exists', async () => { - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - targets: { - build: { - executor: '@nrwl/esbuild:esbuild', - options: { - generatePackageJson: false, - }, - }, - }, - }); - - await update(tree); - - const config = readProjectConfiguration(tree, 'myapp'); - - expect(config.targets.build.options).toEqual({ - generatePackageJson: false, - }); - }); - - it('should set generatePackageJson to true for esbuild targets', async () => { - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - targets: { - build: { - executor: '@nrwl/esbuild:esbuild', - }, - }, - }); - - await update(tree); - - const config = readProjectConfiguration(tree, 'myapp'); - - expect(config.targets.build.options).toEqual({ - generatePackageJson: true, - }); - }); - - it('should ignore targets not using esbuild', async () => { - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - }, - }, - }); - - await update(tree); - - const config = readProjectConfiguration(tree, 'myapp'); - - expect(config.targets.build.options).toBeUndefined(); - }); -}); diff --git a/packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.ts b/packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.ts deleted file mode 100644 index fce27f154885d..0000000000000 --- a/packages/esbuild/src/migrations/update-15-8-7/set-generate-package-json.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { Tree } from '@nx/devkit'; -import { - formatFiles, - getProjects, - updateProjectConfiguration, -} from '@nx/devkit'; - -export default async function update(tree: Tree): Promise { - const projects = getProjects(tree); - - projects.forEach((projectConfig, projectName) => { - let shouldUpdate = false; - - Object.entries(projectConfig.targets).forEach( - ([targetName, targetConfig]) => { - if (targetConfig.executor === '@nrwl/esbuild:esbuild') { - shouldUpdate = true; - - projectConfig.targets[targetName].options ??= {}; - projectConfig.targets[targetName].options.generatePackageJson ??= - true; - } - } - ); - - if (shouldUpdate) { - updateProjectConfiguration(tree, projectName, projectConfig); - } - }); - - await formatFiles(tree); -} diff --git a/packages/eslint/migrations.json b/packages/eslint/migrations.json index 81f6c97b3c883..30c1bbe4ef82d 100644 --- a/packages/eslint/migrations.json +++ b/packages/eslint/migrations.json @@ -1,17 +1,5 @@ { "generators": { - "add-eslint-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Stop hashing eslint config files for build targets and dependent tasks", - "factory": "./src/migrations/update-15-0-0/add-eslint-inputs" - }, - "add-eslint-ignore": { - "cli": "nx", - "version": "15.7.1-beta.0", - "description": "Add node_modules to root eslint ignore", - "factory": "./src/migrations/update-15-7-1/add-eslint-ignore" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", diff --git a/packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.spec.ts b/packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.spec.ts deleted file mode 100644 index 6b1321903566d..0000000000000 --- a/packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.spec.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - Tree, - addProjectConfiguration, - readNxJson, - updateNxJson, -} from '@nx/devkit'; -import addEslintInputs from './add-eslint-inputs'; -import { ESLINT_CONFIG_FILENAMES } from '../../utils/config-file'; - -describe('15.0.0 migration (add-eslint-inputs)', () => { - let tree: Tree; - - describe('production', () => { - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - lint: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - lint2: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - }); - - test.each(ESLINT_CONFIG_FILENAMES)( - 'should ignore %p for production', - async (eslintConfigFilename) => { - tree.write(eslintConfigFilename, '{}'); - - await addEslintInputs(tree); - - const updated = readNxJson(tree); - - expect(updated.namedInputs.production).toEqual([ - 'default', - `!{projectRoot}/${eslintConfigFilename}`, - ]); - } - ); - - test.each(ESLINT_CONFIG_FILENAMES)( - 'should add %p to all lint targets', - async (eslintConfigFilename) => { - tree.write(eslintConfigFilename, '{}'); - - await addEslintInputs(tree); - - const updated = readNxJson(tree); - const result = ['default', `{workspaceRoot}/${eslintConfigFilename}`]; - - expect(updated.targetDefaults.lint.inputs).toEqual(result); - expect(updated.targetDefaults.lint2.inputs).toEqual(result); - } - ); - }); - - describe('development', () => { - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - lint: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - lint2: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - }); - - test.each(ESLINT_CONFIG_FILENAMES)( - 'should not add `!{projectRoot}/%s` if `workspaceConfiguration.namedInputs` is undefined', - async (eslintConfigFilename) => { - tree.write(eslintConfigFilename, '{}'); - - await addEslintInputs(tree); - - const updated = readNxJson(tree); - - expect(updated.namedInputs?.production).toBeUndefined(); - } - ); - - test.each(ESLINT_CONFIG_FILENAMES)( - 'should not add `!{projectRoot}/%s` if `workspaceConfiguration.namedInputs.production` is undefined', - async (eslintConfigFilename) => { - updateNxJson(tree, { - namedInputs: {}, - }); - - tree.write(eslintConfigFilename, '{}'); - - await addEslintInputs(tree); - - const updated = readNxJson(tree); - - expect(updated.namedInputs?.production).toBeUndefined(); - } - ); - }); - - describe('lintTargetDefaults.input fallback values', () => { - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - lint: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - lint2: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - }); - - test.each(ESLINT_CONFIG_FILENAMES)( - 'should not override `targetDefaults.lint.inputs` with `%s` as there was a default target set in the workspace config', - async (eslintConfigFilename) => { - updateNxJson(tree, { - targetDefaults: { - lint: { - inputs: ['{workspaceRoot}/.eslintrc.default'], - }, - }, - }); - - tree.write(eslintConfigFilename, '{}'); - - await addEslintInputs(tree); - - const updated = readNxJson(tree); - - expect(updated.targetDefaults.lint.inputs).toEqual([ - '{workspaceRoot}/.eslintrc.default', - ]); - expect(updated.targetDefaults.lint2.inputs).toEqual([ - 'default', - `{workspaceRoot}/${eslintConfigFilename}`, - ]); - } - ); - - it('should return `default` if there is no globalEslintFile', async () => { - await addEslintInputs(tree); - - const updated = readNxJson(tree); - - expect(updated.targetDefaults.lint.inputs).toEqual(['default']); - expect(updated.targetDefaults.lint2.inputs).toEqual(['default']); - }); - }); -}); diff --git a/packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.ts b/packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.ts deleted file mode 100644 index c9bcd1b79c1ba..0000000000000 --- a/packages/eslint/src/migrations/update-15-0-0/add-eslint-inputs.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - formatFiles, - joinPathFragments, - readNxJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import { getEslintTargets } from '../../generators/utils/eslint-targets'; -import { ESLINT_CONFIG_FILENAMES } from '../../utils/config-file'; - -export default async function addEslintInputs(tree: Tree) { - const nxJson = readNxJson(tree); - - const globalEslintFile = ESLINT_CONFIG_FILENAMES.find((file) => - tree.exists(file) - ); - - if (globalEslintFile && nxJson.namedInputs?.production) { - const productionFileset = new Set(nxJson.namedInputs.production); - - productionFileset.add(`!{projectRoot}/${globalEslintFile}`); - - nxJson.namedInputs.production = Array.from(productionFileset); - } - - for (const targetName of getEslintTargets(tree)) { - nxJson.targetDefaults ??= {}; - - const lintTargetDefaults = (nxJson.targetDefaults[targetName] ??= {}); - - lintTargetDefaults.inputs ??= [ - 'default', - ...(globalEslintFile - ? [joinPathFragments('{workspaceRoot}', globalEslintFile)] - : []), - ]; - } - - updateNxJson(tree, nxJson); - - await formatFiles(tree); -} diff --git a/packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.spec.ts b/packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.spec.ts deleted file mode 100644 index a52f1d8a20098..0000000000000 --- a/packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.spec.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { - addProjectConfiguration, - readJson, - readNxJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import addEslintIgnore from './add-eslint-ignore'; - -describe('15.7.1 migration (add-eslintignore)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - }, - }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - lint: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - lint2: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - }); - - it('should not add .eslintignore if eslint config does not exist', async () => { - await addEslintIgnore(tree); - expect(tree.exists('.eslintignore')).toBeFalsy(); - }); - - it('should add .eslintignore if it does not exist', async () => { - ensureGlobalConfig(tree); - - await addEslintIgnore(tree); - - expect(tree.exists('.eslintignore')).toBeTruthy(); - expect(tree.read('.eslintignore', 'utf-8')).toEqual('node_modules\n'); - }); - - it('should add node_modules if missing in .eslintignore', async () => { - ensureGlobalConfig(tree); - - const original = 'dist\ntmp\n'; - tree.write('.eslintignore', original); - - await addEslintIgnore(tree); - - expect(tree.read('.eslintignore', 'utf-8')).toEqual( - `node_modules\n${original}` - ); - }); - - it('should not add node_modules if already in .eslintignore', async () => { - ensureGlobalConfig(tree); - - const original = `dist\nnode_modules\ntmp\n`; - tree.write('.eslintignore', original); - - await addEslintIgnore(tree); - - expect(tree.read('.eslintignore', 'utf-8')).toEqual(original); - }); - - it('should add lint target', async () => { - ensureGlobalConfig(tree); - - await addEslintIgnore(tree); - - expect(tree.exists('.eslintignore')).toBeTruthy(); - expect(readJson(tree, 'nx.json').targetDefaults).toMatchInlineSnapshot(` - { - "lint": { - "inputs": [ - "default", - "{workspaceRoot}/.eslintrc.json", - ], - }, - "lint2": { - "inputs": [ - "default", - "{workspaceRoot}/.eslintrc.json", - ], - }, - } - `); - }); -}); - -function ensureGlobalConfig(tree: Tree) { - tree.write('.eslintrc.json', '{}'); -} diff --git a/packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.ts b/packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.ts deleted file mode 100644 index 6fc6f60a7d24b..0000000000000 --- a/packages/eslint/src/migrations/update-15-7-1/add-eslint-ignore.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - formatFiles, - joinPathFragments, - readJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import { getEslintTargets } from '../../generators/utils/eslint-targets'; -import { ESLINT_CONFIG_FILENAMES } from '../../utils/config-file'; - -export default async function addEslintIgnore(tree: Tree) { - const nxJson = readJson(tree, 'nx.json'); - - const globalEslintFile = ESLINT_CONFIG_FILENAMES.find((file) => - tree.exists(file) - ); - - if (globalEslintFile) { - if (tree.exists('.eslintignore')) { - const content = tree.read('.eslintignore', 'utf-8'); - if (!content.includes('node_modules')) { - tree.write('.eslintignore', `node_modules\n${content}`); - } - } else { - tree.write('.eslintignore', 'node_modules\n'); - } - - for (const targetName of getEslintTargets(tree)) { - nxJson.targetDefaults ??= {}; - const lintTargetDefaults = (nxJson.targetDefaults[targetName] ??= {}); - - const lintIgnorePath = joinPathFragments( - '{workspaceRoot}', - globalEslintFile - ); - - if (lintTargetDefaults.inputs) { - if (!lintTargetDefaults.inputs.includes(lintIgnorePath)) { - lintTargetDefaults.inputs.push(lintIgnorePath); - } - } else { - lintTargetDefaults.inputs = ['default', lintIgnorePath]; - } - } - - updateNxJson(tree, nxJson); - await formatFiles(tree); - } -} diff --git a/packages/expo/migrations.json b/packages/expo/migrations.json index b257f941b8fa1..282036c69bcd1 100644 --- a/packages/expo/migrations.json +++ b/packages/expo/migrations.json @@ -1,23 +1,5 @@ { "generators": { - "change-expo-jest-preset": { - "version": "15.0.3-beta.0", - "cli": "nx", - "description": "Change jest config preset tof expo projects", - "factory": "./src/migrations/update-15-0-3/change-jest-preset" - }, - "add-new-expo-cli-targets": { - "version": "15.0.3-beta.0", - "cli": "nx", - "description": "Add targets for @expo/cli and replace eject target", - "factory": "./src/migrations/update-15-0-3/add-new-expo-cli-targets" - }, - "change-webpack-to-metro": { - "version": "15.8.3-beta.0", - "cli": "nx", - "description": "Change webpack to metro in expo projects", - "factory": "./src/migrations/update-15-8-3/change-webpack-to-metro" - }, "remove-deprecated-expo-targets": { "version": "16.0.0-beta.0", "cli": "nx", @@ -86,295 +68,6 @@ } }, "packageJsonUpdates": { - "15.0.0": { - "version": "15.0.0-beta.0", - "packages": { - "metro-resolver": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "@testing-library/react-native": { - "version": "11.2.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "4.0.13", - "alwaysAddToPackageJson": false - }, - "expo": { - "version": "46.0.13", - "alwaysAddToPackageJson": false - }, - "expo-cli": { - "version": "6.0.6", - "alwaysAddToPackageJson": false - }, - "react-native": { - "version": "0.69.6", - "alwaysAddToPackageJson": false - } - } - }, - "15.0.3": { - "version": "15.0.3-beta.0", - "packages": { - "@testing-library/react-native": { - "version": "11.3.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "5.0.0", - "alwaysAddToPackageJson": false - }, - "expo": { - "version": "46.0.16", - "alwaysAddToPackageJson": false - }, - "expo-cli": { - "version": "6.0.6", - "alwaysAddToPackageJson": false - }, - "eas-cli": { - "version": "2.4.1", - "alwaysAddToPackageJson": false - }, - "@expo/cli": { - "version": "0.3.2", - "alwaysAddToPackageJson": false, - "addToPackageJson": "devDependencies" - } - } - }, - "15.2.2": { - "version": "15.2.2-beta.0", - "packages": { - "metro-resolver": { - "version": "0.73.3", - "alwaysAddToPackageJson": false - } - } - }, - "15.3.0": { - "version": "15.3.0-beta.0", - "packages": { - "@testing-library/react-native": { - "version": "11.5.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "5.3.0", - "alwaysAddToPackageJson": false - }, - "expo": { - "version": "47.0.8", - "alwaysAddToPackageJson": false - }, - "@expo/metro-config": { - "version": "0.5.1", - "alwaysAddToPackageJson": false - }, - "expo-splash-screen": { - "version": "~0.17.5", - "alwaysAddToPackageJson": false - }, - "expo-cli": { - "version": "6.0.8", - "alwaysAddToPackageJson": false - }, - "@expo/cli": { - "version": "0.4.10", - "alwaysAddToPackageJson": false - }, - "eas-cli": { - "version": "2.8.0", - "alwaysAddToPackageJson": false - }, - "babel-preset-expo": { - "version": "~9.2.2", - "alwaysAddToPackageJson": false - }, - "react-native": { - "version": "0.70.5", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.70.7", - "alwaysAddToPackageJson": false - }, - "react-native-svg": { - "version": "13.3.0", - "alwaysAddToPackageJson": false - }, - "@svgr/webpack": { - "version": "^6.5.1", - "alwaysAddToPackageJson": false - } - } - }, - "15.4.3": { - "version": "15.4.3-beta.0", - "packages": { - "expo": { - "version": "47.0.9", - "alwaysAddToPackageJson": false - }, - "@expo/metro-config": { - "version": "0.5.2", - "alwaysAddToPackageJson": false - }, - "@expo/webpack-config": { - "version": "~0.17.3", - "alwaysAddToPackageJson": false, - "addToPackageJson": "dependencies" - }, - "eas-cli": { - "version": "3.1.1", - "alwaysAddToPackageJson": false - }, - "react-native-web": { - "version": "~0.18.10", - "alwaysAddToPackageJson": false - }, - "react-native-svg": { - "version": "13.4.0", - "alwaysAddToPackageJson": false - } - } - }, - "15.6.2": { - "version": "15.6.2-beta.0", - "packages": { - "expo": { - "version": "47.0.13", - "alwaysAddToPackageJson": false - }, - "@expo/webpack-config": { - "version": "~0.17.4", - "alwaysAddToPackageJson": false - }, - "eas-cli": { - "version": "3.3.2", - "alwaysAddToPackageJson": false - }, - "expo-cli": { - "version": "6.1.0", - "alwaysAddToPackageJson": false - }, - "@expo/cli": { - "version": "0.4.11", - "alwaysAddToPackageJson": false - } - } - }, - "15.7.2": { - "version": "15.7.2-beta.0", - "packages": { - "@expo/webpack-config": { - "version": "~18.0.1", - "alwaysAddToPackageJson": false - }, - "eas-cli": { - "version": "3.5.2", - "alwaysAddToPackageJson": false - }, - "expo-cli": { - "version": "6.3.0", - "alwaysAddToPackageJson": false - } - } - }, - "15.8.3": { - "version": "15.8.3-beta.0", - "packages": { - "expo": { - "version": "48.0.4", - "alwaysAddToPackageJson": false - }, - "@expo/metro-config": { - "version": "0.7.1", - "alwaysAddToPackageJson": false - }, - "expo-splash-screen": { - "version": "~0.18.1", - "alwaysAddToPackageJson": false - }, - "expo-status-bar": { - "version": "~1.4.4", - "alwaysAddToPackageJson": false - }, - "expo-cli": { - "version": "6.3.2", - "alwaysAddToPackageJson": false - }, - "@expo/cli": { - "version": "0.6.2", - "alwaysAddToPackageJson": false - }, - "eas-cli": { - "version": "3.7.2", - "alwaysAddToPackageJson": false - }, - "babel-preset-expo": { - "version": "~9.3.0", - "alwaysAddToPackageJson": false - }, - "react": { - "version": "18.2.0", - "alwaysAddToPackageJson": false - }, - "react-dom": { - "version": "18.2.0", - "alwaysAddToPackageJson": false - }, - "react-test-renderer": { - "version": "18.2.0", - "alwaysAddToPackageJson": false - }, - "@types/react": { - "version": "18.0.28", - "alwaysAddToPackageJson": false - }, - "react-native": { - "version": "0.71.3", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.71.3", - "alwaysAddToPackageJson": false - }, - "react-native-web": { - "version": "~0.18.12", - "alwaysAddToPackageJson": false - }, - "metro": { - "version": "0.74.1", - "alwaysAddToPackageJson": false, - "addToPackageJson": "devDependencies" - } - } - }, - "15.8.6": { - "version": "15.8.6-beta.0", - "packages": { - "expo": { - "version": "48.0.6", - "alwaysAddToPackageJson": false - } - } - }, - "15.9.0": { - "version": "15.9.0-beta.0", - "packages": { - "react-native": { - "version": "0.71.4", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.71.4", - "alwaysAddToPackageJson": false - } - } - }, "16.0.0": { "version": "16.0.0-beta.0", "packages": { diff --git a/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts b/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts deleted file mode 100644 index 68cc2483b07c4..0000000000000 --- a/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { addProjectConfiguration, getProjects, Tree } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import update from './add-new-expo-cli-targets'; - -describe('add-eas-update-target', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - addProjectConfiguration(tree, 'product', { - root: 'apps/product', - sourceRoot: 'apps/product/src', - targets: { - start: { - executor: '@nrwl/expo:start', - }, - }, - }); - }); - - it(`should update project.json with target prebuild, install and eject`, async () => { - await update(tree); - - getProjects(tree).forEach((project) => { - expect(project.targets['eject']).toEqual({ - executor: 'nx:run-commands', - options: { - command: `nx prebuild product`, - }, - }); - expect(project.targets['install']).toEqual({ - executor: '@nrwl/expo:install', - options: {}, - }); - expect(project.targets['prebuild']).toEqual({ - executor: '@nrwl/expo:prebuild', - options: {}, - }); - expect(project.targets['update']).toEqual({ - executor: '@nrwl/expo:update', - options: {}, - }); - }); - }); -}); diff --git a/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts b/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts deleted file mode 100644 index 004368eb6e955..0000000000000 --- a/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - Tree, - formatFiles, - getProjects, - updateProjectConfiguration, - offsetFromRoot, -} from '@nx/devkit'; - -/** - * Add new @expo/cli targets: - * - add target prebuild - * - add target install - * - add target update - * - replace target eject - */ -export default async function update(tree: Tree) { - const projects = getProjects(tree); - - for (const [name, config] of projects.entries()) { - if (config.targets?.['start']?.executor === '@nrwl/expo:start') { - if (!config.targets['prebuild']) { - config.targets['prebuild'] = { - executor: '@nrwl/expo:prebuild', - options: {}, - }; - } - if (!config.targets['install']) { - config.targets['install'] = { - executor: '@nrwl/expo:install', - options: {}, - }; - } - if (!config.targets['update']) { - config.targets['update'] = { - executor: '@nrwl/expo:update', - options: {}, - }; - } - if (!config.targets['export']) { - config.targets['export'] = { - executor: '@nrwl/expo:export', - options: { - platform: 'all', - outputDir: `${offsetFromRoot(config.root)}dist/${config.root}`, - }, - }; - } - if (!config.targets['export-web']) { - config.targets['export-web'] = { - executor: '@nrwl/expo:export', - options: { - bundler: 'webpack', - }, - }; - } - config.targets['eject'] = { - executor: 'nx:run-commands', - options: { - command: `nx prebuild ${name}`, - }, - }; - } - - updateProjectConfiguration(tree, name, config); - } - - await formatFiles(tree); -} diff --git a/packages/expo/src/migrations/update-15-0-3/change-jest-preset.spec.ts b/packages/expo/src/migrations/update-15-0-3/change-jest-preset.spec.ts deleted file mode 100644 index 79721f7d7104e..0000000000000 --- a/packages/expo/src/migrations/update-15-0-3/change-jest-preset.spec.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { - addProjectConfiguration, - readJson, - Tree, - updateJson, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import update from './change-jest-preset'; - -describe('Change expo jest preset', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - updateJson(tree, 'package.json', (packageJson) => { - packageJson.devDependencies['jest-expo'] = '*'; - return packageJson; - }); - addProjectConfiguration(tree, 'products', { - root: 'apps/products', - sourceRoot: 'apps/products/src', - targets: { - test: { - executor: '@nrwl/jest:jest', - options: { - jestConfig: 'apps/products/jest.config.ts', - passWithNoTests: true, - }, - }, - }, - }); - }); - - it(`should not remove transfrom if the code does not contain existing preprocessor`, async () => { - tree.write( - 'apps/products/jest.config.ts', - `module.exports = { - preset: 'jest-expo', - };` - ); - await update(tree); - - const jestConfig = tree.read('apps/products/jest.config.ts', 'utf-8'); - expect(jestConfig).toContain(`preset: 'react-native'`); - }); - - it(`should remove transform if the code contains existing preprocessor`, async () => { - tree.write( - 'apps/products/jest.config.ts', - `module.exports = { - preset: 'jest-expo', - testRunner: 'jest-jasmine2', - transform: { - '\\.(js|ts|tsx)$': require.resolve('react-native/jest/preprocessor.js'), - '^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp)$': require.resolve( - 'react-native/jest/assetFileTransformer.js' - ), - } - };` - ); - await update(tree); - - const jestConfig = tree.read('apps/products/jest.config.ts', 'utf-8'); - expect(jestConfig).not.toContain('transfrom'); - expect(jestConfig).not.toContain('testRunner'); - }); - - it(`should rename .babelrc to babel.config.json`, async () => { - tree.write( - 'apps/products/jest.config.ts', - `module.exports = { - preset: 'jest-expo', - };` - ); - tree.write( - 'apps/products/.babelrc', - `{ - "presets": ["module:metro-react-native-babel-preset"] - }` - ); - await update(tree); - - expect(tree.exists('apps/products/.babelrc')).toBeFalsy(); - expect(tree.exists('apps/products/babel.config.json')).toBeTruthy(); - const babelConfigJson = tree.read( - 'apps/products/babel.config.json', - 'utf-8' - ); - expect(babelConfigJson).toContain( - `"presets": ["module:metro-react-native-babel-preset"]` - ); - }); - - it(`should not rename .babelrc to babel.config.json if app is not react native`, async () => { - tree.write( - 'apps/products/jest.config.ts', - `module.exports = { - preset: 'other', - };` - ); - tree.write( - 'apps/products/.babelrc', - `{ - "presets": ["module:metro-react-native-babel-preset"] - }` - ); - await update(tree); - - expect(tree.exists('apps/products/.babelrc')).toBeTruthy(); - expect(tree.exists('apps/products/babel.config.json')).toBeFalsy(); - }); - - it('should remove jest-expo from package.json', async () => { - tree.write( - 'apps/products/jest.config.ts', - `module.exports = { - preset: 'jest-expo', - };` - ); - await update(tree); - const packageJson = readJson(tree, 'package.json'); - expect(packageJson.devDependencies['jest-expo']).toBeUndefined(); - }); -}); diff --git a/packages/expo/src/migrations/update-15-0-3/change-jest-preset.ts b/packages/expo/src/migrations/update-15-0-3/change-jest-preset.ts deleted file mode 100644 index 49b96bde78bca..0000000000000 --- a/packages/expo/src/migrations/update-15-0-3/change-jest-preset.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - formatFiles, - logger, - ProjectConfiguration, - readProjectConfiguration, - stripIndents, - Tree, - updateJson, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { - addPropertyToJestConfig, - removePropertyFromJestConfig, -} from '@nx/jest'; -import { JestExecutorOptions } from '@nx/jest/src/executors/jest/schema'; -import { join } from 'path'; - -/** - * Change the preset in expo's jest config - * - remove transform and testRunner from jest config - * - changes preset from jest-expo to react-native - * - change to babel.config.json - */ -export default async function update(tree: Tree) { - let useJestExpo = false; - forEachExecutorOptions( - tree, - '@nrwl/jest:jest', - (options, projectName) => { - if (options.jestConfig && tree.exists(options.jestConfig)) { - const jestConfig = tree.read(options.jestConfig, 'utf-8'); - - if (jestConfig.includes(`preset: 'jest-expo'`)) { - const project = readProjectConfiguration(tree, projectName); - changePreset(tree, project); - renameBabelJson(tree, project); - useJestExpo = true; - } - } - } - ); - - if (useJestExpo) { - removeJestExpoFromPackageJson(tree); - } - - await formatFiles(tree); -} - -function changePreset(host: Tree, project: ProjectConfiguration) { - const jestConfigPath = project.targets?.test?.options?.jestConfig; - if (!jestConfigPath || !host.exists(jestConfigPath)) return; - try { - removePropertyFromJestConfig(host, jestConfigPath, 'transform'); - removePropertyFromJestConfig(host, jestConfigPath, 'testRunner'); - removePropertyFromJestConfig(host, jestConfigPath, 'preset'); - addPropertyToJestConfig(host, jestConfigPath, 'preset', 'react-native'); - } catch { - logger.error( - stripIndents`Unable to update ${jestConfigPath} for project ${project.root}.` - ); - } -} - -function renameBabelJson(host: Tree, project: ProjectConfiguration) { - const babelrcPath = join(project.root, '.babelrc'); - const babelJsonPath = join(project.root, 'babel.config.json'); - if (!host.exists(babelrcPath)) { - return; - } - try { - const buffer = host.read(babelrcPath); - if (!buffer) { - return; - } - host.write(babelJsonPath, buffer); - host.delete(babelrcPath); - } catch { - logger.error( - stripIndents`Unable to rename from ${babelrcPath} to ${babelJsonPath} for project ${project.root}.` - ); - } -} - -function removeJestExpoFromPackageJson(tree: Tree) { - updateJson(tree, 'package.json', (packageJson) => { - delete packageJson.devDependencies['jest-expo']; - return packageJson; - }); -} diff --git a/packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.spec.ts b/packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.spec.ts deleted file mode 100644 index 628528af7a39f..0000000000000 --- a/packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { - addProjectConfiguration, - getProjects, - readJson, - Tree, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import update from './change-webpack-to-metro'; - -describe('change-webpack-to-metro', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - addProjectConfiguration(tree, 'product', { - root: 'apps/product', - sourceRoot: 'apps/product/src', - targets: { - start: { - executor: '@nrwl/expo:start', - }, - 'export-web': { - executor: '@nrwl/expo:export', - options: {}, - }, - }, - }); - tree.write( - `apps/product/app.json`, - JSON.stringify({ - expo: { - web: { - bundler: 'webpack', - }, - }, - }) - ); - }); - - it(`should update project.json with target export-web and change app.json`, async () => { - await update(tree); - - getProjects(tree).forEach((project) => { - expect(project.targets['export-web']).toEqual({ - executor: '@nrwl/expo:export', - options: { - bundler: 'metro', - }, - }); - - expect(project.targets['web']).toBeUndefined(); - const appJson = readJson(tree, `apps/product/app.json`); - expect(appJson.expo.web.bundler).toEqual('metro'); - }); - }); -}); diff --git a/packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.ts b/packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.ts deleted file mode 100644 index 4f641478b9918..0000000000000 --- a/packages/expo/src/migrations/update-15-8-3/change-webpack-to-metro.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - Tree, - formatFiles, - getProjects, - updateProjectConfiguration, - updateJson, -} from '@nx/devkit'; - -/** - * Change webpack to metro - * - change target export-web - * - delete webpack.config.js - * - delete @expo/webpack-config dependency - */ -export default async function update(tree: Tree) { - const projects = getProjects(tree); - - for (const [name, config] of projects.entries()) { - if (config.targets?.['start']?.executor === '@nrwl/expo:start') { - if (config.targets['web']) { - delete config.targets['web']; - } - if (config.targets['export-web']) { - config.targets['export-web'].options.bundler = 'metro'; - } - - updateJson(tree, `${config.root}/app.json`, (appJson) => { - if (appJson.expo?.web) { - appJson.expo.web.bundler = 'metro'; - } - return appJson; - }); - } - - updateProjectConfiguration(tree, name, config); - } - - await formatFiles(tree); -} diff --git a/packages/jest/migrations.json b/packages/jest/migrations.json index 74bec910818b0..3dd6db6fb1198 100644 --- a/packages/jest/migrations.json +++ b/packages/jest/migrations.json @@ -1,23 +1,5 @@ { "generators": { - "add-jest-inputs": { - "version": "15.0.0-beta.0", - "cli": "nx", - "description": "Stop hashing jest spec files and config files for build targets and dependent tasks", - "factory": "./src/migrations/update-15-0-0/add-jest-inputs" - }, - "update-configs-jest-29": { - "version": "15.8.0-beta.0", - "cli": "nx", - "description": "Update jest configs to support jest 29 changes (https://jestjs.io/docs/upgrading-to-jest29)", - "factory": "./src/migrations/update-15-8-0/update-configs-jest-29" - }, - "update-tests-jest-29": { - "version": "15.8.0-beta.0", - "cli": "nx", - "description": "Update jest test files to support jest 29 changes (https://jestjs.io/docs/upgrading-to-jest29)", - "factory": "./src/migrations/update-15-8-0/update-tests-jest-29" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -37,52 +19,6 @@ } }, "packageJsonUpdates": { - "15.0.1-beta.3": { - "version": "15.0.1-beta.3", - "packages": { - "jest-environment-jsdom": { - "version": "~28.1.1", - "addToPackageJson": "devDependencies" - } - } - }, - "15.8.0": { - "version": "15.8.0-beta.0", - "packages": { - "jest": { - "version": "~29.4.1", - "alwaysAddToPackageJson": false - }, - "@types/jest": { - "version": "~29.4.0", - "alwaysAddToPackageJson": false - }, - "expect": { - "version": "~29.4.1", - "alwaysAddToPackageJson": false - }, - "@jest/globals": { - "version": "~29.4.1", - "alwaysAddToPackageJson": false - }, - "jest-jasmine2": { - "version": "~29.4.1", - "alwaysAddToPackageJson": false - }, - "jest-environment-jsdom": { - "version": "~29.4.1", - "alwaysAddToPackageJson": false - }, - "ts-jest": { - "version": "~29.0.5", - "alwaysAddToPackageJson": false - }, - "babel-jest": { - "version": "~29.4.1", - "alwaysAddToPackageJson": false - } - } - }, "16.0.0": { "version": "16.0.0-beta.4", "packages": { diff --git a/packages/jest/src/migrations/update-15-0-0/add-jest-inputs.spec.ts b/packages/jest/src/migrations/update-15-0-0/add-jest-inputs.spec.ts deleted file mode 100644 index 9fd8ef0627b8c..0000000000000 --- a/packages/jest/src/migrations/update-15-0-0/add-jest-inputs.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readNxJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import addJestInputs from './add-jest-inputs'; - -describe('15.0.0 migration (add-jest-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add inputs configuration for jest targets', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - test: { - executor: '@nrwl/jest:jest', - options: {}, - }, - test2: { - executor: '@nrwl/jest:jest', - options: {}, - }, - notTest: { - executor: 'nx:run-commands', - }, - }, - }); - tree.write('jest.preset.js', ''); - - await addJestInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", - "!{projectRoot}/tsconfig.spec.json", - "!{projectRoot}/jest.config.[jt]s", - ], - "sharedGlobals": [], - }, - "targetDefaults": { - "test": { - "inputs": [ - "default", - "^production", - "{workspaceRoot}/jest.preset.js", - ], - }, - "test2": { - "inputs": [ - "default", - "^production", - "{workspaceRoot}/jest.preset.js", - ], - }, - }, - } - `); - }); -}); diff --git a/packages/jest/src/migrations/update-15-0-0/add-jest-inputs.ts b/packages/jest/src/migrations/update-15-0-0/add-jest-inputs.ts deleted file mode 100644 index 0199b24771083..0000000000000 --- a/packages/jest/src/migrations/update-15-0-0/add-jest-inputs.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { formatFiles, readNxJson, Tree, updateNxJson } from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; - -export default async function (tree: Tree) { - const nxJson = readNxJson(tree); - - const jestTargets = getJestTargetNames(tree); - const hasProductionFileset = !!nxJson.namedInputs?.production; - - if (jestTargets.size > 0 && hasProductionFileset) { - const productionFileset = new Set(nxJson.namedInputs.production); - for (const exclusion of [ - '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)', - '!{projectRoot}/tsconfig.spec.json', - '!{projectRoot}/jest.config.[jt]s', - ]) { - productionFileset.add(exclusion); - } - nxJson.namedInputs.production = Array.from(productionFileset); - } - - for (const targetName of jestTargets) { - nxJson.targetDefaults ??= {}; - const jestTargetDefaults = (nxJson.targetDefaults[targetName] ??= {}); - - jestTargetDefaults.inputs ??= [ - 'default', - hasProductionFileset ? '^production' : '^default', - ...(tree.exists('jest.preset.js') - ? ['{workspaceRoot}/jest.preset.js'] - : []), - ]; - } - - updateNxJson(tree, nxJson); - - await formatFiles(tree); -} - -function getJestTargetNames(tree: Tree) { - const jestTargetNames = new Set(); - forEachExecutorOptions(tree, '@nrwl/jest:jest', (_, __, target) => { - jestTargetNames.add(target); - }); - return jestTargetNames; -} diff --git a/packages/jest/src/migrations/update-15-8-0/__snapshots__/update-configs-jest-29.spec.ts.snap b/packages/jest/src/migrations/update-15-8-0/__snapshots__/update-configs-jest-29.spec.ts.snap deleted file mode 100644 index e641653481fc9..0000000000000 --- a/packages/jest/src/migrations/update-15-8-0/__snapshots__/update-configs-jest-29.spec.ts.snap +++ /dev/null @@ -1,493 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Jest Migration - jest 29 update configs should NOT update ts-jest with no globals are preset 1`] = ` -"const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - transform: { - '^.+.(ts|js|html)$': 'ts-jest', - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should add snapshot config with no root preset 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: From within the project directory, run "nx test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should add snapshot config with no root preset 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: From within the project directory, run "nx test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should be idempotent 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should be idempotent 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update globalThis.ngJest.teardown to testEnvironmentOptions 1`] = ` -"globalThis.ngJest = {}; - -export default { - globals: {}, - transform: { - '^.+.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '.(html|svg)$', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - testEnvironmentOptions: { teardown: true }, -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update globalThis.ngJest.teardown to testEnvironmentOptions 2`] = ` -"globalThis.ngJest = { - ngcc: true, -}; - -module.exports = { - globals: {}, - transform: { - '^.+.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '.(html|svg)$', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - testEnvironmentOptions: { - blah: 123, - teardown: false, - }, - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update jest.config.ts 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update jest.config.ts 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update root preset 1`] = ` -"const nxPreset = require('@nrwl/jest/preset').default; - -module.exports = { - ...nxPreset, - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update root preset 2`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update root preset 3`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should update root preset if ts-jest is preset 1`] = ` -"const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - transform: { - '^.+.(ts|js|html)$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should work if not using ts-jest transformer 1`] = ` -"export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};" -`; - -exports[`Jest Migration - jest 29 update configs should work if not using ts-jest transformer 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};" -`; - -exports[`Jest Migration - jest 29 update configs should work snapshotFormat is defined 1`] = ` -"export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - globals: { something: 'else', -abc: [1234, true, {abc: 'yes'}] }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - snapshotFormat: {escapeString: false, printBasicPrototype: true} -};" -`; - -exports[`Jest Migration - jest 29 update configs should work snapshotFormat is defined 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': ['ts-jest', { - tsconfig: '/tsconfig.spec.json' - }], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - globals: { something: 'else', -abc: [1234, true, {abc: 'yes'}] }, - snapshotFormat: {escapeString: false, printBasicPrototype: true} -};" -`; - -exports[`Jest Migration - jest 29 update configs should work with jest-preset-angular 1`] = ` -"export default { - globals: { }, - transform: { - '^.+.(ts|mjs|js|html)$': ['jest-preset-angular', { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};" -`; - -exports[`Jest Migration - jest 29 update configs should work with jest-preset-angular 2`] = ` -"module.exports = { - globals: { }, - transform: { - '^.+.(ts|mjs|js|html)$': ['jest-preset-angular', { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};" -`; - -exports[`Jest Migration - jest 29 update configs should work with multiple projects + configs 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should work with multiple projects + configs 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should work with multiple projects + configs 3`] = ` -"/* eslint-disable */ -export default { - displayName: 'another-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/another-lib', -}; -" -`; - -exports[`Jest Migration - jest 29 update configs should work with multiple projects + configs 4`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; diff --git a/packages/jest/src/migrations/update-15-8-0/__snapshots__/update-tests-jest-29.spec.ts.snap b/packages/jest/src/migrations/update-15-8-0/__snapshots__/update-tests-jest-29.spec.ts.snap deleted file mode 100644 index 29fe6f352a35b..0000000000000 --- a/packages/jest/src/migrations/update-15-8-0/__snapshots__/update-tests-jest-29.spec.ts.snap +++ /dev/null @@ -1,199 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Jest Migration - jest 29 mocked usage in tests should be idempotent 1`] = ` -"import { Mocked, MockedShallow } from 'jest-mock'; -import { expect, jest, test } from '@jest/globals'; -import { song } from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, { shallow: true }).mock.calls).toHaveLength( - 1 - ); -}); -" -`; - -exports[`Jest Migration - jest 29 mocked usage in tests should be idempotent 2`] = ` -"const { Mocked, MockedShallow } = require('jest-mock'); -const { expect, jest, test } = require('@jest/globals'); -const { song } = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, { shallow: true }).mock.calls).toHaveLength( - 1 - ); -}); -" -`; - -exports[`Jest Migration - jest 29 mocked usage in tests should be idempotent 3`] = ` -"import { Mocked, MockedShallow } from 'jest-mock'; -import { expect, jest, test } from '@jest/globals'; -import { song } from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, { shallow: true }).mock.calls).toHaveLength( - 1 - ); -}); -" -`; - -exports[`Jest Migration - jest 29 mocked usage in tests should be idempotent 4`] = ` -"const { Mocked, MockedShallow } = require('jest-mock'); -const { expect, jest, test } = require('@jest/globals'); -const { song } = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, { shallow: true }).mock.calls).toHaveLength( - 1 - ); -}); -" -`; - -exports[`Jest Migration - jest 29 mocked usage in tests should not update anything if there are no tests 1`] = ` -"import { Mocked, MockedShallow } from 'jest-mock'; -import { expect, jest, test } from '@jest/globals'; -import { song } from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, { shallow: true }).mock.calls).toHaveLength( - 1 - ); -}); -" -`; - -exports[`Jest Migration - jest 29 mocked usage in tests should not update anything if there are no tests 2`] = ` -"const { Mocked, MockedShallow } = require('jest-mock'); -const { expect, jest, test } = require('@jest/globals'); -const { song } = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, { shallow: true }).mock.calls).toHaveLength( - 1 - ); -}); -" -`; diff --git a/packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.spec.ts b/packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.spec.ts deleted file mode 100644 index fa1877e9b7a51..0000000000000 --- a/packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.spec.ts +++ /dev/null @@ -1,490 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - ProjectGraph, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { updateConfigsJest29 } from './update-configs-jest-29'; -import { libraryGenerator } from '@nx/js'; - -let projectGraph: ProjectGraph; -jest.mock('@nx/devkit', () => ({ - ...jest.requireActual('@nx/devkit'), - createProjectGraphAsync: jest.fn().mockImplementation(async () => { - return projectGraph; - }), -})); - -describe('Jest Migration - jest 29 update configs', () => { - let tree: Tree; - - let originalEnv: string; - beforeEach(() => { - originalEnv = process.env.NX_ADD_PLUGINS; - process.env.NX_ADD_PLUGINS = 'false'; - }); - afterEach(() => { - process.env.NX_ADD_PLUGINS = originalEnv; - }); - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - afterAll(() => { - jest.resetAllMocks(); - }); - it('should update jest.config.ts', async () => { - await setup(tree, 'my-lib'); - - await updateConfigsJest29(tree); - - const actualJestConfigTs = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(actualJestConfigTs).toMatchSnapshot(); - const actualJestConfigJs = tree.read('libs/my-lib/jest.config.js', 'utf-8'); - expect(actualJestConfigJs).toMatchSnapshot(); - }); - - it('should update root preset', async () => { - await setup(tree, 'my-lib'); - await updateConfigsJest29(tree); - - const actualPreset = tree.read('jest.preset.js', 'utf-8'); - expect(actualPreset).toMatchSnapshot(); - const actualJestConfigTs = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(actualJestConfigTs).toMatchSnapshot(); - const actualJestConfigJs = tree.read('libs/my-lib/jest.config.js', 'utf-8'); - expect(actualJestConfigJs).toMatchSnapshot(); - }); - - it('should update root preset if ts-jest is preset', async () => { - await setup(tree, 'my-lib'); - tree.write( - 'jest.preset.js', - `const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, - transform: { - '^.+\\.(ts|js|html)$': 'ts-jest', - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], -}; -` - ); - - await updateConfigsJest29(tree); - - const actualPreset = tree.read('jest.preset.js', 'utf-8'); - expect(actualPreset).toMatchSnapshot(); - }); - - it('should NOT update ts-jest with no globals are preset', async () => { - await setup(tree, 'my-lib'); - tree.write( - 'jest.preset.js', - `const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - transform: { - '^.+\\.(ts|js|html)$': 'ts-jest', - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], -}; -` - ); - - await updateConfigsJest29(tree); - - const actualPreset = tree.read('jest.preset.js', 'utf-8'); - expect(actualPreset).toMatchSnapshot(); - }); - - it('should add snapshot config with no root preset', async () => { - await setup(tree, 'my-lib'); - - tree.delete('jest.preset.js'); - - await updateConfigsJest29(tree); - - const actualJestConfigTs = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(actualJestConfigTs).toMatchSnapshot(); - const actualJestConfigJs = tree.read('libs/my-lib/jest.config.js', 'utf-8'); - expect(actualJestConfigJs).toMatchSnapshot(); - }); - - it('should work with multiple projects + configs', async () => { - await setup(tree, 'my-lib'); - await setup(tree, 'another-lib', projectGraph); - await updateConfigsJest29(tree); - - const actualJestConfigTs1 = tree.read( - 'libs/my-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs1).toMatchSnapshot(); - const actualJestConfigJs1 = tree.read( - 'libs/my-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs1).toMatchSnapshot(); - - const actualJestConfigTs2 = tree.read( - 'libs/another-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs2).toMatchSnapshot(); - const actualJestConfigJs2 = tree.read( - 'libs/another-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs2).toMatchSnapshot(); - }); - - it('should update globalThis.ngJest.teardown to testEnvironmentOptions ', async () => { - await setup(tree, 'jest-preset-angular'); - tree.write( - `libs/jest-preset-angular/jest.config.ts`, - `globalThis.ngJest = { - teardown: true -} - -export default { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - tree.write( - `libs/jest-preset-angular/jest.config.js`, - ` -globalThis.ngJest = { - ngcc: true, - teardown: false -} - -module.exports = { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - testEnvironmentOptions: { - blah: 123, - }, - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - await updateConfigsJest29(tree); - const jpaJestConfigTs = tree.read( - `libs/jest-preset-angular/jest.config.ts`, - 'utf-8' - ); - expect(jpaJestConfigTs).toMatchSnapshot(); - const jpaJestConfigJs = tree.read( - `libs/jest-preset-angular/jest.config.js`, - 'utf-8' - ); - expect(jpaJestConfigJs).toMatchSnapshot(); - }); - - it('should work with jest-preset-angular', async () => { - await setup(tree, 'jest-preset-angular'); - tree.write( - `libs/jest-preset-angular/jest.config.ts`, - `export default { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - tree.write( - `libs/jest-preset-angular/jest.config.js`, - `module.exports = { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - await updateConfigsJest29(tree); - const jpaJestConfigTs = tree.read( - `libs/jest-preset-angular/jest.config.ts`, - 'utf-8' - ); - expect(jpaJestConfigTs).toMatchSnapshot(); - const jpaJestConfigJs = tree.read( - `libs/jest-preset-angular/jest.config.js`, - 'utf-8' - ); - expect(jpaJestConfigJs).toMatchSnapshot(); - }); - - it('should work if not using ts-jest transformer', async () => { - await setup(tree, 'no-ts-jest'); - tree.write( - `libs/no-ts-jest/jest.config.ts`, - `export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - tree.write( - `libs/no-ts-jest/jest.config.js`, - `module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - - await updateConfigsJest29(tree); - const noTsJestConfigTs = tree.read( - `libs/no-ts-jest/jest.config.ts`, - 'utf-8' - ); - expect(noTsJestConfigTs).toMatchSnapshot(); - const noTsJestConfigJs = tree.read( - `libs/no-ts-jest/jest.config.js`, - 'utf-8' - ); - expect(noTsJestConfigJs).toMatchSnapshot(); - }); - - it('should work snapshotFormat is defined', async () => { - await setup(tree, 'no-ts-jest'); - tree.write( - `libs/no-ts-jest/jest.config.ts`, - `export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - snapshotFormat: {escapeString: false, printBasicPrototype: true} -};` - ); - tree.write( - `libs/no-ts-jest/jest.config.js`, - `module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'] - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, - snapshotFormat: {escapeString: false, printBasicPrototype: true} -};` - ); - - await updateConfigsJest29(tree); - const snapshotJestConfigTs = tree.read( - 'libs/no-ts-jest/jest.config.ts', - 'utf-8' - ); - expect(snapshotJestConfigTs).toMatchSnapshot(); - const snapshotJestConfigJs = tree.read( - `libs/no-ts-jest/jest.config.js`, - 'utf-8' - ); - expect(snapshotJestConfigJs).toMatchSnapshot(); - }); - it('should be idempotent', async () => { - await setup(tree, 'my-lib'); - - await updateConfigsJest29(tree); - - const actualJestConfigTs1 = tree.read( - 'libs/my-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs1).toMatchSnapshot(); - const actualJestConfigJs1 = tree.read( - 'libs/my-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs1).toMatchSnapshot(); - - await updateConfigsJest29(tree); - - const actualJestConfigTs2 = tree.read( - 'libs/my-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs2).toEqual(actualJestConfigTs1); - const actualJestConfigJs2 = tree.read( - 'libs/my-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs2).toEqual(actualJestConfigJs1); - }); -}); - -async function setup(tree: Tree, name: string, existingGraph?: ProjectGraph) { - await libraryGenerator(tree, { - name, - }); - const projectConfig = readProjectConfiguration(tree, name); - projectConfig.targets['test'] = { - ...projectConfig.targets['test'], - executor: '@nrwl/jest:jest', - configurations: { - ci: { - ci: true, - }, - other: { - jestConfig: `libs/${name}/jest.config.js`, - }, - }, - }; - - updateProjectConfiguration(tree, name, projectConfig); - tree.write( - `libs/${name}/jest.config.ts`, - `/* eslint-disable */ -export default { - displayName: '${name}', - preset: '../../jest.preset.js', - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - } - }, - transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest' - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/${name}' -}; -` - ); - - tree.write( - `libs/${name}/jest.config.js`, - `module.exports = { -transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest' -}, -// I am a comment and shouldn't be removed -moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], -globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, -/** - * Multi-line comment shouldn't be removed - */ -displayName: 'jest', -testEnvironment: 'node', -preset: '../../jest.preset.js' -}; -` - ); - - tree.write( - 'jest.config.ts', - tree - .read('jest.config.ts') - .toString() - .replace(new RegExp('@nx/jest', 'g'), '@nrwl/jest') - ); - - tree.write( - 'jest.preset.js', - tree - .read('jest.preset.js') - .toString() - .replace(new RegExp('@nx/jest', 'g'), '@nrwl/jest') - ); - - projectGraph = { - dependencies: { - ...existingGraph?.dependencies, - }, - nodes: { - ...existingGraph?.nodes, - [name]: { - name, - type: 'lib', - data: projectConfig, - } as any, - }, - }; -} diff --git a/packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.ts b/packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.ts deleted file mode 100644 index 94de36bb33e57..0000000000000 --- a/packages/jest/src/migrations/update-15-8-0/update-configs-jest-29.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { - createProjectGraphAsync, - formatFiles, - logger, - stripIndents, - Tree, -} from '@nx/devkit'; -import { forEachExecutorOptionsInGraph } from '@nx/devkit/src/generators/executor-options-utils'; -import { TS_QUERY_JEST_CONFIG_PREFIX } from '../../utils/ast-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import * as ts from 'typescript'; -import { JestExecutorOptions } from '../../executors/jest/schema'; -import { findRootJestPreset } from '../../utils/config/find-root-jest-files'; - -export async function updateConfigsJest29(tree: Tree) { - const rootPreset = findRootJestPreset(tree); - const targetsWithJest = new Set(); - // have to use graph so the negative configuration targets are expanded - const graph = await createProjectGraphAsync(); - forEachExecutorOptionsInGraph( - graph, - '@nrwl/jest:jest', - (options, projectName, targetName) => { - if (options.jestConfig && tree.exists(options.jestConfig)) { - targetsWithJest.add(targetName); - // if the default root preset exists or if the project doesn't have a 'preset' configured - // -> update snapshot config - if (!rootPreset || !hasPresetConfigured(tree, options.jestConfig)) { - addSnapshotOptionsToConfig( - tree, - options.jestConfig, - `From within the project directory, run "nx test --update-snapshot"` - ); - } - updateTsJestOptions(tree, options.jestConfig); - updateNgJestOptions(tree, options.jestConfig); - } - } - ); - - if (rootPreset && tree.exists(rootPreset)) { - const cmd = `"nx affected --targets=${Array.from(targetsWithJest).join( - ',' - )} --update-snapshot"`; - addSnapshotOptionsToConfig(tree, rootPreset, cmd); - updateTsJestOptions(tree, rootPreset); - updateNgJestOptions(tree, rootPreset); - } - - await formatFiles(tree); - logger.info(stripIndents`NX Jest Snapshot format changed in v29. -By default Nx kept the older style to prevent breaking of existing tests with snapshots. -It's recommend you update to the latest format. -You can do this in your project's jest config file. -Remove the snapshotFormat property and re-run tests with the --update-snapshot flag. -More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format`); -} - -function addSnapshotOptionsToConfig( - tree: Tree, - configPath: string, - updateSnapshotExample: string -) { - const config = tree.read(configPath, 'utf-8'); - const hasSnapshotOptions = tsquery.query( - config, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="snapshotFormat"])` - ); - if (hasSnapshotOptions.length > 0) { - return; - } - const updatedConfig = tsquery.replace( - config, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression`, - (node: ts.ObjectLiteralExpression) => { - return `{ -${node.properties.map((p) => getNodeWithComments(config, p)).join(',\n')}, -/* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: ${updateSnapshotExample} - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ -snapshotFormat: { escapeString: true, printBasicPrototype: true } -}`; - }, - { visitAllChildren: false } - ); - - tree.write(configPath, updatedConfig); -} - -function hasPresetConfigured(tree: Tree, configPath: string): boolean { - const contents = tree.read(configPath, 'utf-8'); - - return ( - tsquery.query( - contents, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="preset"])` - )?.length > 0 - ); -} - -function updateTsJestOptions(tree: Tree, configPath: string) { - // query for the globals property, if they don't have one then there's nothing to modify. - const contents = tree.read(configPath, 'utf-8'); - let tsJestGlobalsConfig: string; - const noTsJestGlobals = tsquery.replace( - contents, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="globals"])`, - (node: ts.PropertyAssignment) => { - if (tsJestGlobalsConfig) { - logger.warn( - stripIndents`Found more than one "globals" object in the jest config, ${configPath} - Will use the first one` - ); - return; - } - tsJestGlobalsConfig = getGlobalTsJestConfig(node); - return getGlobalConfigWithoutTsJest(node); - } - ); - - if (!tsJestGlobalsConfig) { - return; - } - - const updatedTsJestTransformer = tsquery.replace( - noTsJestGlobals, - `${TS_QUERY_JEST_CONFIG_PREFIX}> ObjectLiteralExpression PropertyAssignment:has(Identifier[name="transform"]) PropertyAssignment > :has(StringLiteral[value="ts-jest"], StringLiteral[value="jest-preset-angular"])`, - (node: ts.StringLiteral) => { - return `[${node.getText()}, ${tsJestGlobalsConfig}]`; - } - ); - - tree.write(configPath, updatedTsJestTransformer); -} - -function updateNgJestOptions(tree: Tree, configPath: string) { - const contents = tree.read(configPath, 'utf-8'); - - let ngJestTeardownConfig: string; - const noTeardownConfig = tsquery.replace( - contents, - 'BinaryExpression:has(PropertyAccessExpression:has(Identifier[name=ngJest])) PropertyAssignment:has(Identifier[name=teardown])', - (node: ts.PropertyAssignment) => { - ngJestTeardownConfig = node.initializer.getText(); - return ' '; - } - ); - - if (!ngJestTeardownConfig) { - return; - } - - let maybeUpdatedTestEnvOpts = tsquery.replace( - noTeardownConfig, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="testEnvironmentOptions"]) ObjectLiteralExpression`, - (node: ts.ObjectLiteralExpression) => { - return `{ - ${node.properties - .map((p) => getNodeWithComments(noTeardownConfig, p)) - .join(',\n')}, - teardown: ${ngJestTeardownConfig} - }`; - } - ); - - if (maybeUpdatedTestEnvOpts !== noTeardownConfig) { - tree.write(configPath, maybeUpdatedTestEnvOpts); - return; - } - // didn't find existing testEnvironmentOptions, so add the new property - - const updatedConfig = tsquery.replace( - maybeUpdatedTestEnvOpts, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression`, - (node: ts.ObjectLiteralExpression) => { - return `{ -${node.properties - .map((p) => getNodeWithComments(maybeUpdatedTestEnvOpts, p)) - .join(',\n')}, -testEnvironmentOptions: { teardown: ${ngJestTeardownConfig} }, -}`; - }, - { visitAllChildren: false } - ); - tree.write(configPath, updatedConfig); -} - -function getGlobalTsJestConfig(node: ts.PropertyAssignment): string { - const globalObject = node.initializer as ts.ObjectLiteralExpression; - const foundConfig = globalObject.properties.find( - (p) => ts.isPropertyAssignment(p) && p.name.getText().includes('ts-jest') - ) as ts.PropertyAssignment; - - return foundConfig?.initializer?.getText() || ''; -} - -function getGlobalConfigWithoutTsJest(node: ts.PropertyAssignment): string { - const globalObject = node?.initializer as ts.ObjectLiteralExpression; - const withoutTsJest = globalObject?.properties?.filter((p) => { - return !( - ts.isPropertyAssignment(p) && p.name.getText().includes('ts-jest') - ); - }); - - const globalConfigs = withoutTsJest.map((c) => c.getText()).join(',\n'); - return `globals: { ${globalConfigs} }`; -} - -function getNodeWithComments(fullText: string, node: ts.Node) { - const commentRanges = ts.getLeadingCommentRanges( - fullText, - node.getFullStart() - ); - - if (commentRanges?.length > 0) { - const withComments = `${commentRanges - .map((r) => fullText.slice(r.pos, r.end)) - .join('\n')}\n${node.getText()}`; - return withComments; - } - return node.getText(); -} - -export default updateConfigsJest29; diff --git a/packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.spec.ts b/packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.spec.ts deleted file mode 100644 index f249e4cea8424..0000000000000 --- a/packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.spec.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { - ProjectGraph, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { libraryGenerator } from '@nx/js'; -import { updateTestsJest29 } from './update-tests-jest-29'; - -let projectGraph: ProjectGraph; -jest.mock('@nx/devkit', () => ({ - ...jest.requireActual('@nx/devkit'), - createProjectGraphAsync: jest - .fn() - .mockImplementation(async () => projectGraph), -})); -describe('Jest Migration - jest 29 mocked usage in tests', () => { - let tree: Tree; - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should not update anything if there are no tests', async () => { - await setup(tree, 'my-lib'); - const expected = tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8'); - await updateTestsJest29(tree); - expect( - tree.read('libs/my-lib/src/file-one.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/file-two.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect(tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8')).toEqual( - expected - ); - }); - it('should be idempotent', async () => { - await setup(tree, 'my-lib'); - - const expected = tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8'); - - await updateTestsJest29(tree); - - expect( - tree.read('libs/my-lib/src/file-one.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/file-two.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect(tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8')).toEqual( - expected - ); - - await updateTestsJest29(tree); - - expect( - tree.read('libs/my-lib/src/file-one.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/file-two.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect(tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8')).toEqual( - expected - ); - }); -}); - -async function setup(tree: Tree, name: string) { - await libraryGenerator(tree, { - name, - }); - const projectConfig = readProjectConfiguration(tree, name); - projectConfig.targets['test'] = { - ...projectConfig.targets['test'], - executor: '@nrwl/jest:jest', - configurations: { - ci: { - ci: true, - }, - other: { - jestConfig: `libs/${name}/jest.config.js`, - }, - }, - }; - - updateProjectConfiguration(tree, name, projectConfig); - - tree.write( - `libs/${name}/jest.config.js`, - `module.exports = { -transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest' -}, -moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], -globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - } - }, -displayName: 'jest', -testEnvironment: 'node', -preset: '../../jest.preset.js' -}; - -` - ); - tree.write( - `libs/${name}/src/file-one.spec.ts`, - ` -import{ MaybeMockedDeep, MaybeMocked } from 'jest-mock'; -import {expect, jest, test} from '@jest/globals'; -import {song} from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); - ` - ); - tree.write( - `libs/${name}/src/file-two.spec.ts`, - ` -const { MaybeMockedDeep, MaybeMocked } = require('jest-mock'); -const {expect, jest, test} = require('@jest/globals'); -const {song} = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -` - ); - projectGraph = { - dependencies: {}, - nodes: { - [name]: { - name, - type: 'lib', - data: projectConfig, - } as any, - }, - }; -} diff --git a/packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.ts b/packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.ts deleted file mode 100644 index e8642d1587b4a..0000000000000 --- a/packages/jest/src/migrations/update-15-8-0/update-tests-jest-29.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { - createProjectGraphAsync, - formatFiles, - readProjectConfiguration, - Tree, - visitNotIgnoredFiles, -} from '@nx/devkit'; -import { forEachExecutorOptionsInGraph } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { - CallExpression, - ImportDeclaration, - VariableStatement, -} from 'typescript'; -import type { JestExecutorOptions } from '../../executors/jest/schema'; -import { TEST_FILE_PATTERN } from '../../utils/ast-utils'; - -export async function updateTestsJest29(tree: Tree) { - const graph = await createProjectGraphAsync(); - forEachExecutorOptionsInGraph( - graph, - '@nrwl/jest:jest', - (options, projectName) => { - const projectConfig = readProjectConfiguration(tree, projectName); - visitNotIgnoredFiles( - tree, - projectConfig.sourceRoot || projectConfig.root, - (file) => { - if (!TEST_FILE_PATTERN.test(file)) { - return; - } - updateJestMockTypes(tree, file); - updateJestMocked(tree, file); - } - ); - } - ); - await formatFiles(tree); -} - -export function updateJestMockTypes(tree: Tree, filePath: string) { - const contents = tree.read(filePath, 'utf-8'); - const updatedContent = tsquery.replace( - contents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="MaybeMockedDeep"], Identifier[name="MaybeMocked"]):has(StringLiteral[value="jest-mock"])', - (node: ImportDeclaration | VariableStatement) => { - const text = node.getText(); - return ( - text - // MaybeMockedDeep and MaybeMocked now are exported as Mocked and MockedShallow - .replace('MaybeMockedDeep', 'Mocked') - .replace('MaybeMocked', 'MockedShallow') - ); - } - ); - tree.write(filePath, updatedContent); -} - -export function updateJestMocked(tree: Tree, filePath: string) { - const contents = tree.read(filePath, 'utf-8'); - const jestGlobalNodes = tsquery.query( - contents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="jest"]):has(StringLiteral[value="@jest/globals"])' - ); - - // this only applies if using jest from @jest/globals - if (jestGlobalNodes.length === 0) { - return; - } - - const updatedJestMockTypes = tsquery.replace( - contents, - 'CallExpression:has(Identifier[name="jest"]):has(Identifier[name="mocked"])', - (node: CallExpression) => { - if ( - node.arguments.length === 2 && - node.getText().startsWith('jest.mocked(') - ) { - const text = node.getText(); - // jest.mocked(someObject, true); => jest.mocked(someObject); - if (node.arguments[1].getText() === 'true') { - return text.replace(/,\s*true/g, ''); - } - // jest.mocked(someObject, false); => jest.mocked(someObject, {shallow: true}); - // opt into the new behavior unless explicitly opting out - if (node.arguments[1].getText() === 'false') { - return text.replace('false', '{shallow: true}'); - } - } - } - ); - - tree.write(filePath, updatedJestMockTypes); -} - -export default updateTestsJest29; diff --git a/packages/js/migrations.json b/packages/js/migrations.json index 3a4cbcec685aa..58423f41a02b6 100644 --- a/packages/js/migrations.json +++ b/packages/js/migrations.json @@ -1,11 +1,5 @@ { "generators": { - "rename-swcrc-config": { - "cli": "nx", - "version": "15.8.0-beta.0", - "description": "Rename .lib.swcrc to .swcrc for better SWC support throughout the workspace", - "factory": "./src/migrations/update-15-8-0/rename-swcrc-config" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -32,18 +26,6 @@ } }, "packageJsonUpdates": { - "15.8.0": { - "version": "15.8.0-beta.2", - "x-prompt": "Do you want to update to TypeScript v4.9?", - "requires": { - "typescript": ">=4.8.2 <4.9.0" - }, - "packages": { - "typescript": { - "version": "~4.9.5" - } - } - }, "16.0.0": { "version": "16.0.0-beta.3", "packages": { diff --git a/packages/js/package.json b/packages/js/package.json index 376e217d02178..221f9b5d84ccb 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -37,7 +37,6 @@ "@babel/preset-env": "^7.23.2", "@babel/preset-typescript": "^7.22.5", "@babel/runtime": "^7.22.6", - "@phenomnomnominal/tsquery": "~5.0.1", "babel-plugin-const-enum": "^1.0.1", "babel-plugin-macros": "^2.8.0", "babel-plugin-transform-typescript-metadata": "^0.3.1", diff --git a/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.spec.ts b/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.spec.ts deleted file mode 100644 index c8fca2d0fce0b..0000000000000 --- a/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.spec.ts +++ /dev/null @@ -1,119 +0,0 @@ -import 'nx/src/internal-testing-utils/mock-project-graph'; - -import { - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { libraryGenerator } from '../../generators/library/library'; -import renameSwcrcConfig from './rename-swcrc-config'; - -describe('Rename swcrc file migration', () => { - let tree: Tree; - - let originalEnv: string; - beforeEach(() => { - originalEnv = process.env.NX_ADD_PLUGINS; - process.env.NX_ADD_PLUGINS = 'false'; - }); - afterEach(() => { - process.env.NX_ADD_PLUGINS = originalEnv; - }); - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should migrate .lib.swcrc to .swcrc', async () => { - await setup(tree); - await renameSwcrcConfig(tree); - - expect(tree.exists('libs/my-lib/.lib.swcrc')).toBeFalsy(); - expect(tree.exists('libs/my-lib/.swcrc')).toBeTruthy(); - - const jestConfig = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(jestConfig).toContain(`fs.readFileSync(\`\${__dirname}/.swcrc\``); - expect(jestConfig).toContain('swcJestConfig.swcrc = false'); - }); - - it('should migrate custom path .lib.swcrc', async () => { - await setup(tree); - customSwcrcPath(tree); - - await renameSwcrcConfig(tree); - - expect(tree.exists('libs/my-lib/src/.lib.swcrc')).toBeFalsy(); - expect(tree.exists('libs/my-lib/src/.swcrc')).toBeTruthy(); - - const projectConfig = readProjectConfiguration(tree, 'my-lib'); - expect(projectConfig.targets.build.options.swcrc).toEqual( - 'libs/my-lib/src/.swcrc' - ); - }); - - it('should do nothing if custom path swcrc is not named .lib.swcrc', async () => { - await setup(tree); - customSwcrcPath(tree, true); - - await renameSwcrcConfig(tree); - - expect(tree.exists('libs/my-lib/src/.custom.swcrc')).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/.swcrc')).toBeFalsy(); - - const projectConfig = readProjectConfiguration(tree, 'my-lib'); - expect(projectConfig.targets.build.options.swcrc).toEqual( - 'libs/my-lib/src/.custom.swcrc' - ); - }); -}); - -async function setup(tree: Tree) { - await libraryGenerator(tree, { - name: 'my-lib', - bundler: 'swc', - unitTestRunner: 'jest', - config: 'project', - }); - - const projectConfig = readProjectConfiguration(tree, 'my-lib'); - projectConfig.targets.build.executor = '@nrwl/js:swc'; - projectConfig.targets.test.executor = '@nrwl/jest:jest'; - updateProjectConfiguration(tree, 'my-lib', projectConfig); - - tree.rename('libs/my-lib/.swcrc', 'libs/my-lib/.lib.swcrc'); - tree.write( - 'libs/my-lib/jest.config.ts', - ` -const fs = require('fs'); - -// Reading the SWC compilation config and remove the "exclude" -// for the test files to be compiled by SWC -const { exclude: _, ...swcJestConfig } = JSON.parse( - fs.readFileSync(\`\${__dirname}/.lib.swcrc\`, 'utf-8') -); - -module.exports = { - displayName: 'my-lib', - preset: '../../jest.preset.js', - transform: { - '^.+\\.[tj]s$': ['@swc/jest', swcJestConfig], - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/packages/vite', -}; -` - ); -} - -function customSwcrcPath(tree: Tree, custom = false) { - tree.rename( - 'libs/my-lib/.lib.swcrc', - custom ? 'libs/my-lib/src/.custom.swcrc' : 'libs/my-lib/src/.lib.swcrc' - ); - const projectConfig = readProjectConfiguration(tree, 'my-lib'); - projectConfig.targets.build.options.swcrc = custom - ? 'libs/my-lib/src/.custom.swcrc' - : 'libs/my-lib/src/.lib.swcrc'; - updateProjectConfiguration(tree, 'my-lib', projectConfig); -} diff --git a/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.ts b/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.ts deleted file mode 100644 index b36dd6e3ce343..0000000000000 --- a/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { - formatFiles, - getProjects, - joinPathFragments, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { SwcExecutorOptions } from '../../utils/schema'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import type { TemplateSpan } from 'typescript'; - -export default async function (tree: Tree) { - let changesMade = false; - const projects = getProjects(tree); - - forEachExecutorOptions( - tree, - '@nrwl/js:swc', - (_, projectName, target, configurationName) => { - const projectConfiguration = projects.get(projectName); - const executorOptions: SwcExecutorOptions = configurationName - ? projectConfiguration.targets[target].configurations[configurationName] - : projectConfiguration.targets[target].options; - // if the project uses a custom path to swcrc file - // and only if it's the default name - if ( - executorOptions.swcrc && - executorOptions.swcrc.includes('.lib.swcrc') - ) { - const newSwcrc = executorOptions.swcrc.replace('.lib.swcrc', '.swcrc'); - // rename the swcrc file first - tree.rename(executorOptions.swcrc, newSwcrc); - // then update the executor options - executorOptions.swcrc = newSwcrc; - changesMade = true; - } - - const libSwcrcPath = - joinPathFragments(projectConfiguration.root, '.lib.swcrc') || - joinPathFragments(projectConfiguration.sourceRoot, '.lib.swcrc'); - const isLibSwcrcExist = tree.exists(libSwcrcPath); - - if (isLibSwcrcExist) { - tree.rename(libSwcrcPath, libSwcrcPath.replace('.lib.swcrc', '.swcrc')); - changesMade = true; - } - - updateProjectConfiguration(tree, projectName, projectConfiguration); - } - ); - - forEachExecutorOptions( - tree, - '@nrwl/jest:jest', - (_, projectName, target, configurationName) => { - const projectConfiguration = projects.get(projectName); - const executorOptions = configurationName - ? projectConfiguration.targets[target].configurations[configurationName] - : projectConfiguration.targets[target].options; - - const isJestConfigExist = - executorOptions.jestConfig && tree.exists(executorOptions.jestConfig); - - if (isJestConfigExist) { - const jestConfig = tree.read(executorOptions.jestConfig, 'utf-8'); - - const jsonParseNodes = tsquery.query( - jestConfig, - ':matches(CallExpression:has(Identifier[name="JSON"]):has(Identifier[name="parse"]))' - ); - - if (jsonParseNodes.length) { - // if we already assign false to swcrc, skip - if (jestConfig.includes('.swcrc = false')) { - return; - } - - let updatedJestConfig = tsquery.replace( - jestConfig, - 'CallExpression:has(Identifier[name="JSON"]):has(Identifier[name="parse"]) TemplateSpan', - (templateSpan: TemplateSpan) => { - if (templateSpan.literal.text === '/.lib.swcrc') { - return templateSpan - .getFullText() - .replace('.lib.swcrc', '.swcrc'); - } - return ''; - } - ); - - updatedJestConfig = tsquery.replace( - updatedJestConfig, - ':matches(ExportAssignment, BinaryExpression:has(Identifier[name="module"]):has(Identifier[name="exports"]))', - (node) => { - return ` - -// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves. -// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude" -if (swcJestConfig.swcrc === undefined) { - swcJestConfig.swcrc = false; -} - -${node.getFullText()} -`; - } - ); - - tree.write(executorOptions.jestConfig, updatedJestConfig); - changesMade = true; - } - } - } - ); - - if (changesMade) { - await formatFiles(tree); - } -} diff --git a/packages/next/migrations.json b/packages/next/migrations.json index 2ad0651291a74..073a90fbea070 100644 --- a/packages/next/migrations.json +++ b/packages/next/migrations.json @@ -1,11 +1,5 @@ { "generators": { - "add-style-packages": { - "cli": "nx", - "version": "15.8.8-beta.0", - "description": "Add less and stylus packages if used.", - "factory": "./src/migrations/update-15-8-8/add-style-packages" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -32,40 +26,6 @@ } }, "packageJsonUpdates": { - "15.0.4": { - "version": "15.0.4-beta.0", - "packages": { - "next": { - "version": "13.0.0", - "alwaysAddToPackageJson": false - }, - "eslint-config-next": { - "version": "13.0.0", - "alwaysAddToPackageJson": false - }, - "less-loader": { - "version": "11.1.0", - "alwaysAddToPackageJson": false - }, - "stylus-loader": { - "version": "7.1.0", - "alwaysAddToPackageJson": false - } - } - }, - "15.4.5": { - "version": "15.4.5-beta.0", - "packages": { - "next": { - "version": "13.1.1", - "alwaysAddToPackageJson": false - }, - "eslint-config-next": { - "version": "13.1.1", - "alwaysAddToPackageJson": false - } - } - }, "16.0.0": { "version": "16.0.0-beta.0", "packages": { diff --git a/packages/next/src/executors/build/lib/create-next-config-file.ts b/packages/next/src/executors/build/lib/create-next-config-file.ts index 89b66c7d5d2bc..e4e0bf1983462 100644 --- a/packages/next/src/executors/build/lib/create-next-config-file.ts +++ b/packages/next/src/executors/build/lib/create-next-config-file.ts @@ -16,7 +16,7 @@ import { writeFileSync, } from 'fs-extra'; import { dirname, extname, join, relative } from 'path'; -import { findNodes } from 'nx/src/utils/typescript'; +import { findNodes } from '@nx/js'; import type { NextBuildBuilderOptions } from '../../../utils/types'; diff --git a/packages/next/src/migrations/update-15-8-8/add-style-packages.spec.ts b/packages/next/src/migrations/update-15-8-8/add-style-packages.spec.ts deleted file mode 100644 index e094fe0023546..0000000000000 --- a/packages/next/src/migrations/update-15-8-8/add-style-packages.spec.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { writeJson, readJson, Tree, addProjectConfiguration } from '@nx/devkit'; -import update from './add-style-packages'; - -describe('Add less if needed', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace(); - }); - - it('should add less if used', async () => { - writeJson(tree, 'package.json', { - dependencies: {}, - devDependencies: {}, - }); - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - targets: { - build: { - executor: '@nrwl/next:build', - }, - }, - }); - tree.write( - `myapp/next.config.js`, - `require('@nrwl/next/plugins/with-less')` - ); - - await update(tree); - - const packageJson = readJson(tree, 'package.json'); - expect(packageJson).toEqual({ - dependencies: {}, - devDependencies: { less: '3.12.2' }, - }); - }); - - it('should not add anything if less not used by Next.js app', async () => { - writeJson(tree, 'package.json', { - dependencies: {}, - devDependencies: {}, - }); - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - targets: { - build: { - executor: '@nrwl/next:build', - }, - }, - }); - tree.write(`myapp/next.config.js`, `require('@nrwl/next/plugins/with-nx')`); - - await update(tree); - - const packageJson = readJson(tree, 'package.json'); - expect(packageJson).toEqual({ - dependencies: {}, - devDependencies: {}, - }); - }); - - it('should not add anything if no Next.js apps are in workspace', async () => { - writeJson(tree, 'package.json', { - dependencies: {}, - devDependencies: {}, - }); - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - }, - }, - }); - - await update(tree); - - const packageJson = readJson(tree, 'package.json'); - expect(packageJson).toEqual({ - dependencies: {}, - devDependencies: {}, - }); - }); -}); diff --git a/packages/next/src/migrations/update-15-8-8/add-style-packages.ts b/packages/next/src/migrations/update-15-8-8/add-style-packages.ts deleted file mode 100644 index 6eb868756b4ce..0000000000000 --- a/packages/next/src/migrations/update-15-8-8/add-style-packages.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - addDependenciesToPackageJson, - getProjects, - joinPathFragments, - Tree, -} from '@nx/devkit'; - -export async function update(tree: Tree) { - const projects = getProjects(tree); - const missingDeps = {}; - - for (const [, config] of projects) { - if ( - config.targets?.build?.executor === '@nrwl/next:build' && - tree.exists(joinPathFragments(config.root, 'next.config.js')) - ) { - const nextConfigContent = tree.read( - joinPathFragments(config.root, 'next.config.js'), - 'utf-8' - ); - - if (nextConfigContent.includes('@nrwl/next/plugins/with-less')) { - missingDeps['less'] = '3.12.2'; - } - - if (nextConfigContent.includes('@nrwl/next/plugins/with-stylus')) { - missingDeps['stylus'] = '^0.55.0'; - } - } - } - - return addDependenciesToPackageJson(tree, {}, missingDeps); -} - -export default update; diff --git a/packages/nx/migrations.json b/packages/nx/migrations.json index 67f30f4a0d611..b0971f8ac4bac 100644 --- a/packages/nx/migrations.json +++ b/packages/nx/migrations.json @@ -1,29 +1,5 @@ { "generators": { - "15.0.0-migrate-to-inputs": { - "cli": "nx", - "version": "15.0.0-beta.1", - "description": "Replace implicitDependencies with namedInputs + target inputs", - "implementation": "./src/migrations/update-15-0-0/migrate-to-inputs" - }, - "15.0.0-prefix-outputs": { - "cli": "nx", - "version": "15.0.0-beta.1", - "description": "Prefix outputs with {workspaceRoot}/{projectRoot} if needed", - "implementation": "./src/migrations/update-15-0-0/prefix-outputs" - }, - "15.1.0-set-project-names": { - "cli": "nx", - "version": "15.0.12-beta.1", - "description": "Set project names in project.json files", - "implementation": "./src/migrations/update-15-1-0/set-project-names" - }, - "15.8.2-update-nx-wrapper": { - "cli": "nx", - "version": "15.8.2-beta.0", - "description": "Updates the nx wrapper.", - "implementation": "./src/migrations/update-15-8-2/update-nxw" - }, "16.0.0-remove-nrwl-cli": { "cli": "nx", "version": "16.0.0-beta.0", diff --git a/packages/nx/src/command-line/release/changelog.ts b/packages/nx/src/command-line/release/changelog.ts index 3974f567700dd..25d34f162c7a6 100644 --- a/packages/nx/src/command-line/release/changelog.ts +++ b/packages/nx/src/command-line/release/changelog.ts @@ -21,7 +21,6 @@ import { isCI } from '../../utils/is-ci'; import { output } from '../../utils/output'; import { handleErrors } from '../../utils/params'; import { joinPathFragments } from '../../utils/path'; -import { getRootTsConfigPath } from '../../utils/typescript'; import { workspaceRoot } from '../../utils/workspace-root'; import { ChangelogOptions } from './command-object'; import { @@ -58,6 +57,7 @@ import { handleDuplicateGitTags, noDiffInChangelogMessage, } from './utils/shared'; +import { getRootTsConfigPath } from '../../plugins/js/utils/typescript'; export interface NxReleaseChangelogResult { workspaceChangelog?: { diff --git a/packages/nx/src/command-line/release/command-object.ts b/packages/nx/src/command-line/release/command-object.ts index 32200c2e03eb6..d4ef6596543fc 100644 --- a/packages/nx/src/command-line/release/command-object.ts +++ b/packages/nx/src/command-line/release/command-object.ts @@ -1,5 +1,4 @@ import { Argv, CommandModule, showHelp } from 'yargs'; -import { readNxJson } from '../../project-graph/file-utils'; import { logger } from '../../utils/logger'; import { OutputStyle, @@ -10,6 +9,7 @@ import { withRunManyOptions, } from '../yargs-utils/shared-options'; import { VersionData } from './utils/shared'; +import { readNxJson } from '../../config/nx-json'; export interface NxReleaseArgs { groups?: string[]; diff --git a/packages/nx/src/command-line/report/report.ts b/packages/nx/src/command-line/report/report.ts index 435c69a39e000..52013c09edca0 100644 --- a/packages/nx/src/command-line/report/report.ts +++ b/packages/nx/src/command-line/report/report.ts @@ -43,6 +43,7 @@ export const patternsWeIgnoreInCommunityReport: Array = [ ]; const LINE_SEPARATOR = '---------------------------------------'; + /** * Reports relevant version numbers for adding to an Nx issue report * @@ -294,7 +295,7 @@ export function findRegisteredPluginsBeingUsed(nxJson: NxJsonConfiguration) { export function findInstalledPackagesWeCareAbout() { const packagesWeMayCareAbout: Record = {}; - // TODO (v19): Remove workaround for hiding @nrwl packages when matching @nx package is found. + // TODO (v20): Remove workaround for hiding @nrwl packages when matching @nx package is found. const packageChangeMap: Record = { '@nrwl/nx-plugin': '@nx/plugin', '@nx/plugin': '@nrwl/nx-plugin', diff --git a/packages/nx/src/config/workspaces.spec.ts b/packages/nx/src/config/to-project-name.spec.ts similarity index 97% rename from packages/nx/src/config/workspaces.spec.ts rename to packages/nx/src/config/to-project-name.spec.ts index b85882b2eba6c..1a36f37f775a1 100644 --- a/packages/nx/src/config/workspaces.spec.ts +++ b/packages/nx/src/config/to-project-name.spec.ts @@ -1,4 +1,4 @@ -import { toProjectName } from './workspaces'; +import { toProjectName } from './to-project-name'; import { TempFs } from '../internal-testing-utils/temp-fs'; import { withEnvironmentVariables } from '../internal-testing-utils/with-environment'; import { retrieveProjectConfigurations } from '../project-graph/utils/retrieve-workspace-files'; diff --git a/packages/nx/src/config/to-project-name.ts b/packages/nx/src/config/to-project-name.ts new file mode 100644 index 0000000000000..367a9bb15df5c --- /dev/null +++ b/packages/nx/src/config/to-project-name.ts @@ -0,0 +1,10 @@ +import { dirname } from 'path'; + +/** + * Pulled from toFileName in names from @nx/devkit. + * Todo: Should refactor, not duplicate. + */ +export function toProjectName(fileName: string): string { + const parts = dirname(fileName).split(/[\/\\]/g); + return parts[parts.length - 1].toLowerCase(); +} diff --git a/packages/nx/src/config/workspaces.ts b/packages/nx/src/config/workspaces.ts deleted file mode 100644 index 1401ff5c1f1a2..0000000000000 --- a/packages/nx/src/config/workspaces.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { dirname } from 'path'; -import { - readCachedProjectGraph, - readProjectsConfigurationFromProjectGraph, -} from '../project-graph/project-graph'; - -import type { NxJsonConfiguration } from './nx-json'; -import { readNxJson } from './nx-json'; -import { ProjectsConfigurations } from './workspace-json-project-json'; - -// TODO(v19): remove this class -/** - * @deprecated This will be removed in v19. Use {@link readProjectsConfigurationFromProjectGraph} instead. - */ -export class Workspaces { - constructor(private root: string) {} - - /** - * @deprecated Use {@link readProjectsConfigurationFromProjectGraph} instead. - */ - readWorkspaceConfiguration(): ProjectsConfigurations & NxJsonConfiguration { - const nxJson = readNxJson(this.root); - - return { - ...readProjectsConfigurationFromProjectGraph(readCachedProjectGraph()), - ...nxJson, - }; - } -} - -/** - * Pulled from toFileName in names from @nx/devkit. - * Todo: Should refactor, not duplicate. - */ -export function toProjectName(fileName: string): string { - const parts = dirname(fileName).split(/[\/\\]/g); - return parts[parts.length - 1].toLowerCase(); -} diff --git a/packages/nx/src/devkit-exports.ts b/packages/nx/src/devkit-exports.ts index 1c3dac76c5812..8e5d7dcffe7e0 100644 --- a/packages/nx/src/devkit-exports.ts +++ b/packages/nx/src/devkit-exports.ts @@ -37,12 +37,6 @@ export type { HasherContext, } from './config/misc-interfaces'; -// TODO(v19): Remove this export -/** - * @category Workspace - */ -export { Workspaces } from './config/workspaces'; - export { workspaceLayout } from './config/configuration'; export type { diff --git a/packages/nx/src/hasher/task-hasher.ts b/packages/nx/src/hasher/task-hasher.ts index e8d528d2811ce..93bdbb65636f6 100644 --- a/packages/nx/src/hasher/task-hasher.ts +++ b/packages/nx/src/hasher/task-hasher.ts @@ -40,13 +40,13 @@ export interface Hash { export interface TaskHasher { /** - * @deprecated use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 + * @deprecated use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 * @param task */ hashTask(task: Task): Promise; /** - * @deprecated use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 + * @deprecated use hashTask(task:Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 */ hashTask(task: Task, taskGraph: TaskGraph): Promise; @@ -57,13 +57,13 @@ export interface TaskHasher { ): Promise; /** - * @deprecated use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 + * @deprecated use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 * @param tasks */ hashTasks(tasks: Task[]): Promise; /** - * @deprecated use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v19 + * @deprecated use hashTasks(tasks:Task[], taskGraph: TaskGraph, env: NodeJS.ProcessEnv) instead. This will be removed in v20 */ hashTasks(tasks: Task[], taskGraph: TaskGraph): Promise; diff --git a/packages/nx/src/migrations/update-15-1-0/set-project-names.ts b/packages/nx/src/migrations/update-15-1-0/set-project-names.ts deleted file mode 100644 index f61e283fa3064..0000000000000 --- a/packages/nx/src/migrations/update-15-1-0/set-project-names.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Tree } from '../../generators/tree'; -import { readNxJson } from '../../generators/utils/nx-json'; -import { dirname } from 'path'; -import { readJson, writeJson } from '../../generators/utils/json'; -import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available'; -import { retrieveProjectConfigurationPaths } from '../../project-graph/utils/retrieve-workspace-files'; -import { loadNxPlugins } from '../../project-graph/plugins/internal-api'; - -export default async function (tree: Tree) { - const nxJson = readNxJson(tree); - const [plugins, cleanup] = await loadNxPlugins( - nxJson?.plugins ?? [], - tree.root - ); - const projectFiles = retrieveProjectConfigurationPaths(tree.root, plugins); - const projectJsons = projectFiles.filter((f) => f.endsWith('project.json')); - - for (let f of projectJsons) { - const projectJson = readJson(tree, f); - if (!projectJson.name) { - projectJson.name = toProjectName(dirname(f), nxJson); - writeJson(tree, f, projectJson); - } - } - await formatChangedFilesWithPrettierIfAvailable(tree); - cleanup(); -} - -function toProjectName(directory: string, nxJson: any): string { - let { appsDir, libsDir } = nxJson?.workspaceLayout || {}; - appsDir ??= 'apps'; - libsDir ??= 'libs'; - const parts = directory.split(/[\/\\]/g); - if ([appsDir, libsDir].includes(parts[0])) { - parts.splice(0, 1); - } - return parts.join('-').toLowerCase(); -} diff --git a/packages/nx/src/migrations/update-15-8-2/update-nxw.ts b/packages/nx/src/migrations/update-15-8-2/update-nxw.ts deleted file mode 100644 index a9db089e14598..0000000000000 --- a/packages/nx/src/migrations/update-15-8-2/update-nxw.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Tree } from '../../generators/tree'; -import { updateNxw } from '../../utils/update-nxw'; - -export default async function (tree: Tree) { - updateNxw(tree); -} diff --git a/packages/nx/src/plugins/package-json-workspaces/create-nodes.ts b/packages/nx/src/plugins/package-json-workspaces/create-nodes.ts index cff3d81eeedad..be4f9fdb82661 100644 --- a/packages/nx/src/plugins/package-json-workspaces/create-nodes.ts +++ b/packages/nx/src/plugins/package-json-workspaces/create-nodes.ts @@ -4,7 +4,7 @@ import { dirname, join } from 'node:path'; import { NxJsonConfiguration, readNxJson } from '../../config/nx-json'; import { ProjectConfiguration } from '../../config/workspace-json-project-json'; -import { toProjectName } from '../../config/workspaces'; +import { toProjectName } from '../../config/to-project-name'; import { readJsonFile, readYamlFile } from '../../utils/fileutils'; import { combineGlobPatterns } from '../../utils/globs'; import { NX_PREFIX } from '../../utils/logger'; diff --git a/packages/nx/src/plugins/project-json/build-nodes/project-json.ts b/packages/nx/src/plugins/project-json/build-nodes/project-json.ts index 51d0989504317..59031d6d5c12f 100644 --- a/packages/nx/src/plugins/project-json/build-nodes/project-json.ts +++ b/packages/nx/src/plugins/project-json/build-nodes/project-json.ts @@ -1,7 +1,7 @@ import { dirname, join } from 'node:path'; import { ProjectConfiguration } from '../../../config/workspace-json-project-json'; -import { toProjectName } from '../../../config/workspaces'; +import { toProjectName } from '../../../config/to-project-name'; import { readJsonFile } from '../../../utils/fileutils'; import { NxPluginV2 } from '../../../project-graph/plugins'; import { CreateNodesError } from '../../../project-graph/error-types'; diff --git a/packages/nx/src/project-graph/file-utils.ts b/packages/nx/src/project-graph/file-utils.ts index cd99d0b5cd279..7107547ed9b4a 100644 --- a/packages/nx/src/project-graph/file-utils.ts +++ b/packages/nx/src/project-graph/file-utils.ts @@ -27,7 +27,6 @@ import { getDefaultPluginsSync } from '../utils/nx-plugin.deprecated'; import { minimatch } from 'minimatch'; import { CreateNodesResult } from '../devkit-exports'; import { PackageJsonProjectsNextToProjectJsonPlugin } from '../plugins/project-json/build-nodes/package-json-next-to-project-json'; -import { LoadedNxPlugin } from './plugins/internal-api'; export interface Change { type: string; @@ -133,8 +132,8 @@ function defaultReadFileAtRevision( } /** - * TODO(v19): Remove this function - * @deprecated To get projects use {@link retrieveProjectConfigurations} instead + * TODO(v20): Remove this function + * @deprecated To get projects use {@link retrieveProjectConfigurations} instead. This will be removed in v20. */ export function readWorkspaceConfig(opts: { format: 'angularCli' | 'nx'; @@ -176,11 +175,9 @@ export function readPackageJson(): any { // Original Exports export { FileData }; -// TODO(17): Remove these exports -export { readNxJson, workspaceLayout } from '../config/configuration'; /** - * TODO(v19): Remove this function. + * TODO(v20): Remove this function. */ function getProjectsSyncNoInference(root: string, nxJson: NxJsonConfiguration) { const allConfigFiles = retrieveProjectConfigurationPaths( diff --git a/packages/nx/src/project-graph/plugins/loader.ts b/packages/nx/src/project-graph/plugins/loader.ts index d31625e8418ce..b66d9eb30261a 100644 --- a/packages/nx/src/project-graph/plugins/loader.ts +++ b/packages/nx/src/project-graph/plugins/loader.ts @@ -11,14 +11,12 @@ import { import { readJsonFile } from '../../utils/fileutils'; import { workspaceRoot } from '../../utils/workspace-root'; import { existsSync } from 'node:fs'; -import { readTsConfig } from '../../utils/typescript'; import { registerTranspiler, registerTsConfigPaths, } from '../../plugins/js/utils/register'; import { ProjectRootMappings, - createProjectRootMappingsFromProjectConfigurations, findProjectForPath, } from '../utils/find-project-for-path'; import { normalizePath } from '../../utils/path'; @@ -33,6 +31,7 @@ import { normalizeNxPlugin } from './utils'; import { LoadedNxPlugin } from './internal-api'; import { LoadPluginError } from '../error-types'; import path = require('node:path/posix'); +import { readTsConfig } from '../../plugins/js/utils/typescript'; export function readPluginPackageJson( pluginName: string, diff --git a/packages/nx/src/project-graph/plugins/utils.ts b/packages/nx/src/project-graph/plugins/utils.ts index 13889b8904219..e9009fe1f5d4f 100644 --- a/packages/nx/src/project-graph/plugins/utils.ts +++ b/packages/nx/src/project-graph/plugins/utils.ts @@ -1,6 +1,6 @@ import { dirname } from 'node:path'; -import { toProjectName } from '../../config/workspaces'; +import { toProjectName } from '../../config/to-project-name'; import { combineGlobPatterns } from '../../utils/globs'; import type { NxPluginV1 } from '../../utils/nx-plugin.deprecated'; diff --git a/packages/nx/src/tasks-runner/create-task-graph.ts b/packages/nx/src/tasks-runner/create-task-graph.ts index 41ac9c9b48fe4..581acb1952a17 100644 --- a/packages/nx/src/tasks-runner/create-task-graph.ts +++ b/packages/nx/src/tasks-runner/create-task-graph.ts @@ -345,8 +345,7 @@ export class ProcessTasks { qualifiedTarget, interpolatedOverrides ), - // TODO(v19): Remove cast here after typing is moved back onto TargetConfiguration - cache: (project.data.targets[target] as any).cache, + cache: project.data.targets[target].cache, }; } diff --git a/packages/nx/src/tasks-runner/run-command.ts b/packages/nx/src/tasks-runner/run-command.ts index d4968037dd6e5..2865836f88870 100644 --- a/packages/nx/src/tasks-runner/run-command.ts +++ b/packages/nx/src/tasks-runner/run-command.ts @@ -260,7 +260,7 @@ export async function invokeTasksRunner({ title: `TaskGraph is now required as an argument to hashTask`, bodyLines: [ `The TaskGraph object can be retrieved from the context`, - 'This will result in an error in Nx 19', + 'This will result in an error in Nx 20', ], }); taskGraph_ = taskGraph; @@ -270,7 +270,7 @@ export async function invokeTasksRunner({ title: `The environment variables are now required as an argument to hashTask`, bodyLines: [ `Please pass the environment variables used when running the task`, - 'This will result in an error in Nx 19', + 'This will result in an error in Nx 20', ], }); env = process.env; @@ -287,7 +287,7 @@ export async function invokeTasksRunner({ title: `TaskGraph is now required as an argument to hashTasks`, bodyLines: [ `The TaskGraph object can be retrieved from the context`, - 'This will result in an error in Nx 19', + 'This will result in an error in Nx 20', ], }); taskGraph_ = taskGraph; @@ -297,7 +297,7 @@ export async function invokeTasksRunner({ title: `The environment variables are now required as an argument to hashTasks`, bodyLines: [ `Please pass the environment variables used when running the tasks`, - 'This will result in an error in Nx 19', + 'This will result in an error in Nx 20', ], }); env = process.env; @@ -456,6 +456,7 @@ export function getRunner( throw new Error(`Could not find runner configuration for ${runner}`); } } + function getTasksRunnerPath( runner: string, nxJson: NxJsonConfiguration diff --git a/packages/nx/src/utils/nx-plugin.deprecated.ts b/packages/nx/src/utils/nx-plugin.deprecated.ts index f4bde883ad6d8..4a030fc2c3bf6 100644 --- a/packages/nx/src/utils/nx-plugin.deprecated.ts +++ b/packages/nx/src/utils/nx-plugin.deprecated.ts @@ -37,7 +37,7 @@ export type NxPluginV1 = { }; /** - * @todo(@agentender) v19: Remove this fn when we remove readWorkspaceConfig + * @todo(@agentender) v20: Remove this fn when we remove readWorkspaceConfig */ export function getDefaultPluginsSync(root: string): NxPluginV2[] { const plugins: NxPluginV2[] = [ diff --git a/packages/nx/src/utils/typescript.ts b/packages/nx/src/utils/typescript.ts deleted file mode 100644 index e22673d5cfd18..0000000000000 --- a/packages/nx/src/utils/typescript.ts +++ /dev/null @@ -1,3 +0,0 @@ -// TODO(v19): Nx Devkit 15 depends on this file. Remove this when we no longer support Nx Devkit 15 - -export * from '../plugins/js/utils/typescript'; diff --git a/packages/plugin/executors.json b/packages/plugin/executors.json deleted file mode 100644 index cc20d4f086018..0000000000000 --- a/packages/plugin/executors.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "executors": { - "e2e": { - "implementation": "./src/executors/e2e/e2e.impl", - "schema": "./src/executors/e2e/schema.json", - "description": "Creates and runs the E2E tests for an Nx Plugin.", - "x-deprecated": "@nx/plugin:e2e is deprecated and will be removed in Nx v19. Use @nx/jest:jest instead." - } - } -} diff --git a/packages/plugin/migrations.json b/packages/plugin/migrations.json index 6519989e617bf..38263a21f0a9b 100644 --- a/packages/plugin/migrations.json +++ b/packages/plugin/migrations.json @@ -1,23 +1,5 @@ { "generators": { - "update-15-0-0": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Migrates executor schema files to v2", - "factory": "./src/migrations/update-15-0-0/specify-output-capture" - }, - "update-configs-jest-29": { - "version": "15.9.0-beta.0", - "cli": "nx", - "description": "Update nx plugin jest configs to support jest 29 changes (https://jestjs.io/docs/upgrading-to-jest29)", - "factory": "./src/migrations/update-15-9-0/jest-29-configs" - }, - "update-tests-jest-29": { - "version": "15.9.0-beta.0", - "cli": "nx", - "description": "Update nx plugin jest test files to support jest 29 changes (https://jestjs.io/docs/upgrading-to-jest29)", - "factory": "./src/migrations/update-15-9-0/jest-29-tests" - }, "update-remove-cli-prop": { "version": "16.0.0-beta.1", "cli": "nx", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index c2053ea94f3d8..0ab79ddb1c624 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -22,13 +22,11 @@ }, "homepage": "https://nx.dev", "generators": "./generators.json", - "executors": "./executors.json", "ng-update": { "requirements": {}, "migrations": "./migrations.json" }, "dependencies": { - "@phenomnomnominal/tsquery": "~5.0.1", "fs-extra": "^11.1.0", "tslib": "^2.3.0", "@nx/devkit": "file:../devkit", diff --git a/packages/plugin/src/executors/e2e/e2e.impl.ts b/packages/plugin/src/executors/e2e/e2e.impl.ts deleted file mode 100644 index 27f8f95b7a3ca..0000000000000 --- a/packages/plugin/src/executors/e2e/e2e.impl.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { ExecutorContext } from '@nx/devkit'; - -import { - logger, - output, - parseTargetString, - readTargetOptions, - runExecutor, -} from '@nx/devkit'; -import { JestExecutorOptions } from '@nx/jest/src/executors/jest/schema'; -import { jestExecutor } from '@nx/jest/src/executors/jest/jest.impl'; -import type { NxPluginE2EExecutorOptions } from './schema'; - -// TODO(v19): remove this -export async function* nxPluginE2EExecutor( - options: NxPluginE2EExecutorOptions, - context: ExecutorContext -): AsyncGenerator<{ success: boolean }> { - const { target, ...jestOptions } = options; - - output.warn({ - title: `"@nx/plugin:e2e" is deprecated and will be removed in Nx 19`, - bodyLines: [ - 'Use the "@nx/jest:jest" executor instead and set the following:', - `"dependsOn": ["${target}"]`, - ], - }); - - let success: boolean; - for await (const _ of runBuildTarget(target, context)) { - try { - success = await runTests(jestOptions, context); - } catch (e) { - logger.error(e.message); - success = false; - } - } - - return { success }; -} - -async function* runBuildTarget( - buildTarget: string, - context: ExecutorContext -): AsyncGenerator { - const { project, target, configuration } = parseTargetString( - buildTarget, - context - ); - const buildTargetOptions = readTargetOptions( - { project, target, configuration }, - context - ); - const targetSupportsWatch = Object.keys(buildTargetOptions).includes('watch'); - - for await (const output of await runExecutor<{ success: boolean }>( - { project, target, configuration }, - targetSupportsWatch ? { watch: false } : {}, - context - )) { - if (!output.success) - throw new Error('Could not compile application files.'); - yield output.success; - } -} - -async function runTests( - jestOptions: JestExecutorOptions, - context: ExecutorContext -): Promise { - const { success } = await jestExecutor( - { ...jestOptions, watch: false }, - context - ); - - return success; -} - -export default nxPluginE2EExecutor; diff --git a/packages/plugin/src/executors/e2e/schema.d.ts b/packages/plugin/src/executors/e2e/schema.d.ts deleted file mode 100644 index fe3fa1aaf1869..0000000000000 --- a/packages/plugin/src/executors/e2e/schema.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { JestExecutorOptions } from '@nx/jest/src/executors/jest/schema'; - -export interface NxPluginE2EExecutorOptions extends JestExecutorOptions { - target: string; - jestConfig: string; -} diff --git a/packages/plugin/src/executors/e2e/schema.json b/packages/plugin/src/executors/e2e/schema.json deleted file mode 100644 index d830e71d9d1a0..0000000000000 --- a/packages/plugin/src/executors/e2e/schema.json +++ /dev/null @@ -1,220 +0,0 @@ -{ - "version": 2, - "outputCapture": "direct-nodejs", - "title": "Nx Plugin Playground Target", - "description": "Creates a playground for a Nx Plugin.", - "cli": "nx", - "type": "object", - "properties": { - "target": { - "description": "The build target for the Nx Plugin project.", - "type": "string", - "x-priority": "important" - }, - "jestConfig": { - "type": "string", - "description": "Jest config file.", - "x-completion-type": "file", - "x-completion-glob": "jest.config@(.js|.ts)", - "x-priority": "important" - }, - "tsSpecConfig": { - "type": "string", - "description": "The tsconfig file for specs.", - "x-deprecated": "Use the `tsconfig` property for `ts-jest` in the e2e project `jest.config.js` file. It will be removed in the next major release.", - "x-completion-type": "file", - "x-completion-glob": "tsconfig.*.json", - "x-priority": "important" - }, - "codeCoverage": { - "description": "Indicates that test coverage information should be collected and reported in the output. (https://jestjs.io/docs/cli#--coverageboolean)", - "type": "boolean", - "aliases": ["coverage"] - }, - "config": { - "description": "The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.", - "type": "string" - }, - "clearCache": { - "description": "Deletes the Jest cache directory and then exits without running tests. Will delete Jest's default cache directory. _Note: clearing the cache will reduce performance_.", - "type": "boolean" - }, - "detectOpenHandles": { - "description": "Attempt to collect and print open handles preventing Jest from exiting cleanly (https://jestjs.io/docs/cli#--detectopenhandles)", - "type": "boolean" - }, - "logHeapUsage": { - "description": "Logs the heap usage after every test. Useful to debug memory leaks. Use together with --runInBand and --expose-gc in node.", - "type": "boolean" - }, - "detectLeaks": { - "description": "**EXPERIMENTAL**: Detect memory leaks in tests. After executing a test, it will try to garbage collect the global object used, and fail if it was leaked", - "type": "boolean" - }, - "testFile": { - "description": "The name of the file to test.", - "type": "string", - "x-completion-type": "file", - "x-completion-glob": "**/*.+(spec|test).+(ts|js)" - }, - "tsConfig": { - "description": "The name of the Typescript configuration file. Set the tsconfig option in the jest config file. ", - "type": "string", - "x-deprecated": "Use the ts-jest configuration options in the jest config file instead." - }, - "setupFile": { - "description": "The name of a setup file used by Jest. (use Jest config file https://jestjs.io/docs/en/configuration#setupfilesafterenv-array)", - "type": "string", - "x-deprecated": "Use the setupFilesAfterEnv option in the jest config file. https://jestjs.io/docs/en/configuration#setupfilesafterenv-array" - }, - "bail": { - "alias": "b", - "description": "Exit the test suite immediately after `n` number of failing tests. (https://jestjs.io/docs/cli#--bail)", - "oneOf": [ - { - "type": "number" - }, - { - "type": "boolean" - } - ] - }, - "ci": { - "description": "Whether to run Jest in continuous integration (CI) mode. This option is on by default in most popular CI environments. It will prevent snapshots from being written unless explicitly requested. (https://jestjs.io/docs/cli#--ci)", - "type": "boolean" - }, - "color": { - "alias": "colors", - "description": "Forces test results output color highlighting (even if `stdout` is not a TTY). Set to false if you would like to have no colors. (https://jestjs.io/docs/cli#--colors)", - "type": "boolean" - }, - "findRelatedTests": { - "description": "Find and run the tests that cover a comma separated list of source files that were passed in as arguments. (https://jestjs.io/docs/cli#--findrelatedtests-spaceseparatedlistofsourcefiles)", - "type": "string" - }, - "json": { - "description": "Prints the test results in `JSON`. This mode will send all other test output and user messages to `stderr`. (https://jestjs.io/docs/cli#--json)", - "type": "boolean" - }, - "maxWorkers": { - "alias": "w", - "description": "Specifies the maximum number of workers the worker-pool will spawn for running tests. This defaults to the number of the cores available on your machine. Useful for CI. (its usually best not to override this default) (https://jestjs.io/docs/cli#--maxworkersnumstring)", - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "onlyChanged": { - "alias": "o", - "description": "Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a `git` or `hg` repository at the moment. (https://jestjs.io/docs/cli#--onlychanged)", - "type": "boolean" - }, - "changedSince": { - "description": "Runs tests related to the changes since the provided branch or commit hash. If the current branch has diverged from the given branch, then only changes made locally will be tested. (https://jestjs.io/docs/cli#--changedsince)", - "type": "string" - }, - "outputFile": { - "description": "Write test results to a file when the `--json` option is also specified. (https://jestjs.io/docs/cli#--outputfilefilename)", - "type": "string" - }, - "passWithNoTests": { - "description": "Will not fail if no tests are found (for example while using `--testPathPattern`.) (https://jestjs.io/docs/cli#--passwithnotests)", - "type": "boolean" - }, - "runInBand": { - "alias": "i", - "description": "Run all tests serially in the current process (rather than creating a worker pool of child processes that run tests). This is sometimes useful for debugging, but such use cases are pretty rare. Useful for CI. (https://jestjs.io/docs/cli#--runinband)", - "type": "boolean", - "default": true - }, - "showConfig": { - "description": "Print your Jest config and then exits. (https://jestjs.io/docs/en/cli#--showconfig)", - "type": "boolean" - }, - "silent": { - "description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/cli#--silent)", - "type": "boolean" - }, - "testNamePattern": { - "alias": "t", - "description": "Run only tests with a name that matches the regex pattern. (https://jestjs.io/docs/cli#--testnamepatternregex)", - "type": "string" - }, - "testPathIgnorePatterns": { - "description": "An array of regexp pattern strings that is matched against all tests paths before executing the test. Only run those tests with a path that does not match with the provided regexp expressions. (https://jestjs.io/docs/cli#--testpathignorepatternsregexarray)", - "type": "array", - "items": { - "type": "string" - } - }, - "testPathPattern": { - "description": "An array of regexp pattern strings that is matched against all tests paths before executing the test. (https://jestjs.io/docs/cli#--testpathpatternregex)", - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "colors": { - "description": "Forces test results output highlighting even if stdout is not a TTY. (https://jestjs.io/docs/cli#--colors)", - "type": "boolean" - }, - "reporters": { - "description": "Run tests with specified reporters. Reporter options are not available via CLI. Example with multiple reporters: `jest --reporters=\"default\" --reporters=\"jest-junit\"`. (https://jestjs.io/docs/cli#--reporters)", - "type": "array", - "items": { - "type": "string" - } - }, - "verbose": { - "description": "Display individual test results with the test suite hierarchy. (https://jestjs.io/docs/cli#--verbose)", - "type": "boolean" - }, - "coverageReporters": { - "description": "A list of reporter names that Jest uses when writing coverage reports. Any istanbul reporter.", - "type": "array", - "items": { - "type": "string" - } - }, - "coverageDirectory": { - "description": "The directory where Jest should output its coverage files.", - "type": "string" - }, - "testResultsProcessor": { - "description": "Node module that implements a custom results processor. (https://jestjs.io/docs/en/configuration#testresultsprocessor-string)", - "type": "string" - }, - "updateSnapshot": { - "alias": "u", - "description": "Use this flag to re-record snapshots. Can be used together with a test suite pattern or with `--testNamePattern` to re-record snapshot for test matching the pattern. (https://jestjs.io/docs/cli#--updatesnapshot)", - "type": "boolean" - }, - "useStderr": { - "description": "Divert all output to stderr.", - "type": "boolean" - }, - "watch": { - "description": "Watch files for changes and rerun tests related to changed files. If you want to re-run all tests when a file has changed, use the `--watchAll` option. (https://jestjs.io/docs/cli#--watch)", - "type": "boolean" - }, - "watchAll": { - "description": "Watch files for changes and rerun all tests when something changes. If you want to re-run only the tests that depend on the changed files, use the `--watch` option. (https://jestjs.io/docs/cli#--watchall)", - "type": "boolean" - }, - "testLocationInResults": { - "description": "Adds a location field to test results. Used to report location of a test in a reporter. { \"column\": 4, \"line\": 5 } (https://jestjs.io/docs/cli#--testlocationinresults)", - "type": "boolean" - }, - "testTimeout": { - "description": "Default timeout of a test in milliseconds. Default value: `5000`. (https://jestjs.io/docs/cli#--testtimeoutnumber)", - "type": "number" - } - }, - "additionalProperties": false, - "required": ["target", "jestConfig"] -} diff --git a/packages/plugin/src/migrations/update-15-0-0/specify-output-capture.spec.ts b/packages/plugin/src/migrations/update-15-0-0/specify-output-capture.spec.ts deleted file mode 100644 index 11c36067a09b3..0000000000000 --- a/packages/plugin/src/migrations/update-15-0-0/specify-output-capture.spec.ts +++ /dev/null @@ -1,88 +0,0 @@ -import 'nx/src/internal-testing-utils/mock-project-graph'; - -import { readJson, updateJson } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { Linter } from '@nx/eslint'; -import { assertRunsAgainstNxRepo } from '@nx/devkit/internal-testing-utils'; -import { ExecutorConfig } from 'nx/src/config/misc-interfaces'; -import executorGenerator from '../../generators/executor/executor'; -import pluginGenerator from '../../generators/plugin/plugin'; -import update from './specify-output-capture'; - -const schemaPath = `libs/plugin/src/executors/build/schema.json`; - -describe('update-15-0-0-specify-output-capture', () => { - let originalEnv: string; - beforeEach(() => { - originalEnv = process.env.NX_ADD_PLUGINS; - process.env.NX_ADD_PLUGINS = 'false'; - }); - - afterAll(() => { - process.env.NX_ADD_PLUGINS = originalEnv; - }); - - it('should not change outputCapture if already present', async () => { - const { tree } = await createTreeWithBoilerplate(); - updateJson(tree, schemaPath, (json) => { - delete json.version; - json.outputCapture = 'pipe'; - return json; - }); - await update(tree); - expect( - readJson(tree, schemaPath).version - ).toEqual(2); - expect( - readJson(tree, schemaPath).outputCapture - ).toEqual('pipe'); - }); - - it('should not set outputCapture if version is 2', async () => { - const { tree } = await createTreeWithBoilerplate(); - await update(tree); - expect( - readJson(tree, schemaPath).version - ).toEqual(2); - expect( - readJson(tree, schemaPath).outputCapture - ).toBeUndefined(); - }); - - it('should set outputCapture if version is null', async () => { - const { tree } = await createTreeWithBoilerplate(); - updateJson(tree, schemaPath, (json) => { - delete json.version; - return json; - }); - await update(tree); - expect( - readJson(tree, schemaPath).version - ).toEqual(2); - expect( - readJson(tree, schemaPath).outputCapture - ).toEqual('direct-nodejs'); - }); - - assertRunsAgainstNxRepo(update); -}); - -async function createTreeWithBoilerplate() { - const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - await pluginGenerator(tree, { - name: 'plugin', - compiler: 'tsc', - linter: Linter.EsLint, - skipFormat: false, - skipLintChecks: false, - skipTsConfig: false, - unitTestRunner: 'jest', - }); - await executorGenerator(tree, { - name: 'build', - project: 'plugin', - unitTestRunner: 'jest', - includeHasher: false, - }); - return { tree }; -} diff --git a/packages/plugin/src/migrations/update-15-0-0/specify-output-capture.ts b/packages/plugin/src/migrations/update-15-0-0/specify-output-capture.ts deleted file mode 100644 index bb1efb0579017..0000000000000 --- a/packages/plugin/src/migrations/update-15-0-0/specify-output-capture.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - Tree, - getProjects, - joinPathFragments, - ExecutorsJson, - updateJson, - formatFiles, - readJson, -} from '@nx/devkit'; -import { ExecutorConfig } from 'nx/src/config/misc-interfaces'; -import { PackageJson } from 'nx/src/utils/package-json'; - -export default async function update(tree: Tree): Promise { - for (const [project, { root }] of getProjects(tree)) { - const packageJsonPath = joinPathFragments(root, 'package.json'); - if (!tree.exists(packageJsonPath)) { - continue; - } - const packageJson = readJson(tree, packageJsonPath); - if (!packageJson.executors && !packageJson.builders) { - continue; - } - const paths = [packageJson.executors, packageJson.builders].filter(Boolean); - for (const collectionPathSegment of paths) { - const collectionPath = joinPathFragments(root, collectionPathSegment); - if (!tree.exists(collectionPath)) { - continue; - } - const collectionFile: ExecutorsJson = readJson(tree, collectionPath); - - const collections = [ - collectionFile.builders, - collectionFile.executors, - ].filter(Boolean); - for (const collection of collections) { - if (!collection) { - continue; - } - for (const entry of Object.values(collection)) { - const schemaPath = joinPathFragments(root, entry.schema); - if (tree.exists(schemaPath)) { - updateJson(tree, schemaPath, (json: ExecutorConfig['schema']) => { - if (json.version) { - return json; - } else { - const newProperties: Partial = { - version: 2, - }; - if (!json.outputCapture) { - newProperties.outputCapture = 'direct-nodejs'; - } - return { ...newProperties, ...json }; - } - }); - } - } - } - } - } - await formatFiles(tree); -} diff --git a/packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-configs-jest-29.spec.ts.snap b/packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-configs-jest-29.spec.ts.snap deleted file mode 100644 index beee6714d1cb0..0000000000000 --- a/packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-configs-jest-29.spec.ts.snap +++ /dev/null @@ -1,506 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Nx Plugin Migration - jest 29 update configs should NOT update ts-jest with no globals are preset 1`] = ` -"const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - transform: { - '^.+.(ts|js|html)$': 'ts-jest', - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should add snapshot config with no root preset 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: From within the project directory, run "nx test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should add snapshot config with no root preset 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: From within the project directory, run "nx test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should be idempotent 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should be idempotent 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update globalThis.ngJest.teardown to testEnvironmentOptions 1`] = ` -"globalThis.ngJest = {}; - -export default { - globals: {}, - transform: { - '^.+.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '.(html|svg)$', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - testEnvironmentOptions: { teardown: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update globalThis.ngJest.teardown to testEnvironmentOptions 2`] = ` -"globalThis.ngJest = { - ngcc: true, -}; - -module.exports = { - globals: {}, - transform: { - '^.+.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '.(html|svg)$', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - testEnvironmentOptions: { - blah: 123, - teardown: false, - }, - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update jest.config.ts 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update jest.config.ts 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update root preset 1`] = ` -"const nxPreset = require('@nrwl/jest/preset').default; - -module.exports = { - ...nxPreset, - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update root preset 2`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update root preset 3`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should update root preset if ts-jest is preset 1`] = ` -"const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - transform: { - '^.+.(ts|js|html)$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], - /* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: "nx affected --targets=test --update-snapshot" - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ - snapshotFormat: { escapeString: true, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work if not using ts-jest transformer 1`] = ` -"export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work if not using ts-jest transformer 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work snapshotFormat is defined 1`] = ` -"export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - snapshotFormat: { escapeString: false, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work snapshotFormat is defined 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - snapshotFormat: { escapeString: false, printBasicPrototype: true }, -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work with jest-preset-angular 1`] = ` -"export default { - globals: {}, - transform: { - '^.+.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '.(html|svg)$', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work with jest-preset-angular 2`] = ` -"module.exports = { - globals: {}, - transform: { - '^.+.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '.(html|svg)$', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work with multiple projects + configs 1`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work with multiple projects + configs 2`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work with multiple projects + configs 3`] = ` -"/* eslint-disable */ -export default { - displayName: 'another-lib', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/another-lib', -}; -" -`; - -exports[`Nx Plugin Migration - jest 29 update configs should work with multiple projects + configs 4`] = ` -"module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - // I am a comment and shouldn't be removed - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - globals: { something: 'else', abc: [1234, true, { abc: 'yes' }] }, - /** - * Multi-line comment shouldn't be removed - */ - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -}; -" -`; diff --git a/packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-tests-jest-29.spec.ts.snap b/packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-tests-jest-29.spec.ts.snap deleted file mode 100644 index b34647b746f5c..0000000000000 --- a/packages/plugin/src/migrations/update-15-9-0/__snapshots__/update-tests-jest-29.spec.ts.snap +++ /dev/null @@ -1,187 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Nx Plugin Migration - jest 29 mocked usage in tests should be idempotent 1`] = ` -"import { MaybeMockedDeep, MaybeMocked } from 'jest-mock'; -import { expect, jest, test } from '@jest/globals'; -import { song } from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -" -`; - -exports[`Nx Plugin Migration - jest 29 mocked usage in tests should be idempotent 2`] = ` -"const { MaybeMockedDeep, MaybeMocked } = require('jest-mock'); -const { expect, jest, test } = require('@jest/globals'); -const { song } = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -" -`; - -exports[`Nx Plugin Migration - jest 29 mocked usage in tests should be idempotent 3`] = ` -"import { MaybeMockedDeep, MaybeMocked } from 'jest-mock'; -import { expect, jest, test } from '@jest/globals'; -import { song } from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -" -`; - -exports[`Nx Plugin Migration - jest 29 mocked usage in tests should be idempotent 4`] = ` -"const { MaybeMockedDeep, MaybeMocked } = require('jest-mock'); -const { expect, jest, test } = require('@jest/globals'); -const { song } = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -" -`; - -exports[`Nx Plugin Migration - jest 29 mocked usage in tests should not update anything if there are no tests 1`] = ` -"import { MaybeMockedDeep, MaybeMocked } from 'jest-mock'; -import { expect, jest, test } from '@jest/globals'; -import { song } from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -" -`; - -exports[`Nx Plugin Migration - jest 29 mocked usage in tests should not update anything if there are no tests 2`] = ` -"const { MaybeMockedDeep, MaybeMocked } = require('jest-mock'); -const { expect, jest, test } = require('@jest/globals'); -const { song } = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -" -`; diff --git a/packages/plugin/src/migrations/update-15-9-0/jest-29-configs.ts b/packages/plugin/src/migrations/update-15-9-0/jest-29-configs.ts deleted file mode 100644 index 7d0cdbaf5a17d..0000000000000 --- a/packages/plugin/src/migrations/update-15-9-0/jest-29-configs.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { - createProjectGraphAsync, - formatFiles, - logger, - stripIndents, - Tree, -} from '@nx/devkit'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import * as ts from 'typescript'; -import { forEachExecutorOptionsInGraph } from '@nx/devkit/src/generators/executor-options-utils'; -import { TS_QUERY_JEST_CONFIG_PREFIX } from '@nx/jest/src/utils/ast-utils'; -import { findRootJestPreset } from '@nx/jest/src/utils/config/find-root-jest-files'; -import { JestExecutorOptions } from '@nx/jest/src/executors/jest/schema'; - -// NOTE: this is a copy of the @nrwl/jest v15.8.0 migrations -export async function updateConfigsJest29(tree: Tree) { - const rootPreset = findRootJestPreset(tree); - const targetsWithJest = new Set(); - // have to use graph so the negative configuration targets are expanded - const graph = await createProjectGraphAsync(); - forEachExecutorOptionsInGraph( - graph, - '@nrwl/nx-plugin:e2e', - (options, projectName, targetName) => { - if (options.jestConfig && tree.exists(options.jestConfig)) { - targetsWithJest.add(targetName); - // if the default root preset exists or if the project doesn't have a 'preset' configured - // -> update snapshot config - if (!rootPreset || !hasPresetConfigured(tree, options.jestConfig)) { - addSnapshotOptionsToConfig( - tree, - options.jestConfig, - `From within the project directory, run "nx test --update-snapshot"` - ); - } - updateTsJestOptions(tree, options.jestConfig); - updateNgJestOptions(tree, options.jestConfig); - } - } - ); - - if (rootPreset && tree.exists(rootPreset)) { - const cmd = `"nx affected --targets=${Array.from(targetsWithJest).join( - ',' - )} --update-snapshot"`; - addSnapshotOptionsToConfig(tree, rootPreset, cmd); - updateTsJestOptions(tree, rootPreset); - updateNgJestOptions(tree, rootPreset); - } - - await formatFiles(tree); - logger.info(stripIndents`NX Jest Snapshot format changed in v29. -By default Nx kept the older style to prevent breaking of existing tests with snapshots. -It's recommend you update to the latest format. -You can do this in your project's jest config file. -Remove the snapshotFormat property and re-run tests with the --update-snapshot flag. -More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format`); -} - -function addSnapshotOptionsToConfig( - tree: Tree, - configPath: string, - updateSnapshotExample: string -) { - const config = tree.read(configPath, 'utf-8'); - const hasSnapshotOptions = tsquery.query( - config, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="snapshotFormat"])` - ); - if (hasSnapshotOptions.length > 0) { - return; - } - const updatedConfig = tsquery.replace( - config, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression`, - (node: ts.ObjectLiteralExpression) => { - return `{ -${node.properties.map((p) => getNodeWithComments(config, p)).join(',\n')}, -/* TODO: Update to latest Jest snapshotFormat - * By default Nx has kept the older style of Jest Snapshot formats - * to prevent breaking of any existing tests with snapshots. - * It's recommend you update to the latest format. - * You can do this by removing snapshotFormat property - * and running tests with --update-snapshot flag. - * Example: ${updateSnapshotExample} - * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format - */ -snapshotFormat: { escapeString: true, printBasicPrototype: true } -}`; - }, - { visitAllChildren: false } - ); - - tree.write(configPath, updatedConfig); -} - -function hasPresetConfigured(tree: Tree, configPath: string): boolean { - const contents = tree.read(configPath, 'utf-8'); - - return ( - tsquery.query( - contents, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="preset"])` - )?.length > 0 - ); -} - -function updateTsJestOptions(tree: Tree, configPath: string) { - // query for the globals property, if they don't have one then there's nothing to modify. - const contents = tree.read(configPath, 'utf-8'); - let tsJestGlobalsConfig: string; - const noTsJestGlobals = tsquery.replace( - contents, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="globals"])`, - (node: ts.PropertyAssignment) => { - if (tsJestGlobalsConfig) { - logger.warn( - stripIndents`Found more than one "globals" object in the jest config, ${configPath} - Will use the first one` - ); - return; - } - tsJestGlobalsConfig = getGlobalTsJestConfig(node); - return getGlobalConfigWithoutTsJest(node); - } - ); - - if (!tsJestGlobalsConfig) { - return; - } - - const updatedTsJestTransformer = tsquery.replace( - noTsJestGlobals, - `${TS_QUERY_JEST_CONFIG_PREFIX}> ObjectLiteralExpression PropertyAssignment:has(Identifier[name="transform"]) PropertyAssignment > :has(StringLiteral[value="ts-jest"], StringLiteral[value="jest-preset-angular"])`, - (node: ts.StringLiteral) => { - return `[${node.getText()}, ${tsJestGlobalsConfig}]`; - } - ); - - tree.write(configPath, updatedTsJestTransformer); -} - -function updateNgJestOptions(tree: Tree, configPath: string) { - const contents = tree.read(configPath, 'utf-8'); - - let ngJestTeardownConfig: string; - const noTeardownConfig = tsquery.replace( - contents, - 'BinaryExpression:has(PropertyAccessExpression:has(Identifier[name=ngJest])) PropertyAssignment:has(Identifier[name=teardown])', - (node: ts.PropertyAssignment) => { - ngJestTeardownConfig = node.initializer.getText(); - return ' '; - } - ); - - if (!ngJestTeardownConfig) { - return; - } - - let maybeUpdatedTestEnvOpts = tsquery.replace( - noTeardownConfig, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="testEnvironmentOptions"]) ObjectLiteralExpression`, - (node: ts.ObjectLiteralExpression) => { - return `{ - ${node.properties - .map((p) => getNodeWithComments(noTeardownConfig, p)) - .join(',\n')}, - teardown: ${ngJestTeardownConfig} - }`; - } - ); - - if (maybeUpdatedTestEnvOpts !== noTeardownConfig) { - tree.write(configPath, maybeUpdatedTestEnvOpts); - return; - } - // didn't find existing testEnvironmentOptions, so add the new property - - const updatedConfig = tsquery.replace( - maybeUpdatedTestEnvOpts, - `${TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression`, - (node: ts.ObjectLiteralExpression) => { - return `{ -${node.properties - .map((p) => getNodeWithComments(maybeUpdatedTestEnvOpts, p)) - .join(',\n')}, -testEnvironmentOptions: { teardown: ${ngJestTeardownConfig} }, -}`; - }, - { visitAllChildren: false } - ); - tree.write(configPath, updatedConfig); -} - -function getGlobalTsJestConfig(node: ts.PropertyAssignment): string { - const globalObject = node.initializer as ts.ObjectLiteralExpression; - const foundConfig = globalObject.properties.find( - (p) => ts.isPropertyAssignment(p) && p.name.getText().includes('ts-jest') - ) as ts.PropertyAssignment; - - return foundConfig?.initializer?.getText() || ''; -} - -function getGlobalConfigWithoutTsJest(node: ts.PropertyAssignment): string { - const globalObject = node?.initializer as ts.ObjectLiteralExpression; - const withoutTsJest = globalObject?.properties?.filter((p) => { - return !( - ts.isPropertyAssignment(p) && p.name.getText().includes('ts-jest') - ); - }); - - const globalConfigs = withoutTsJest.map((c) => c.getText()).join(',\n'); - return `globals: { ${globalConfigs} }`; -} - -function getNodeWithComments(fullText: string, node: ts.Node) { - const commentRanges = ts.getLeadingCommentRanges( - fullText, - node.getFullStart() - ); - - if (commentRanges?.length > 0) { - const withComments = `${commentRanges - .map((r) => fullText.slice(r.pos, r.end)) - .join('\n')}\n${node.getText()}`; - return withComments; - } - return node.getText(); -} - -export default updateConfigsJest29; diff --git a/packages/plugin/src/migrations/update-15-9-0/jest-29-tests.ts b/packages/plugin/src/migrations/update-15-9-0/jest-29-tests.ts deleted file mode 100644 index a7045156c21d3..0000000000000 --- a/packages/plugin/src/migrations/update-15-9-0/jest-29-tests.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { - createProjectGraphAsync, - formatFiles, - readProjectConfiguration, - Tree, - visitNotIgnoredFiles, -} from '@nx/devkit'; -import { JestExecutorOptions } from '@nx/jest/src/executors/jest/schema'; -import { TEST_FILE_PATTERN } from '@nx/jest/src/utils/ast-utils'; -import { forEachExecutorOptionsInGraph } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { - CallExpression, - ImportDeclaration, - VariableStatement, -} from 'typescript'; - -// NOTE: this is a copy of the @nrwl/jest v15.8.0 migrations -export async function updateTestsJest29(tree: Tree) { - const graph = await createProjectGraphAsync(); - forEachExecutorOptionsInGraph( - graph, - '@nrwl/nx-plugin:e2e', - (options, projectName) => { - const projectConfig = readProjectConfiguration(tree, projectName); - visitNotIgnoredFiles( - tree, - projectConfig.sourceRoot || projectConfig.root, - (file) => { - if (!TEST_FILE_PATTERN.test(file)) { - return; - } - updateJestMockTypes(tree, file); - updateJestMocked(tree, file); - } - ); - } - ); - await formatFiles(tree); -} - -export function updateJestMockTypes(tree: Tree, filePath: string) { - const contents = tree.read(filePath, 'utf-8'); - const updatedContent = tsquery.replace( - contents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="MaybeMockedDeep"], Identifier[name="MaybeMocked"]):has(StringLiteral[value="jest-mock"])', - (node: ImportDeclaration | VariableStatement) => { - const text = node.getText(); - return ( - text - // MaybeMockedDeep and MaybeMocked now are exported as Mocked and MockedShallow - .replace('MaybeMockedDeep', 'Mocked') - .replace('MaybeMocked', 'MockedShallow') - ); - } - ); - tree.write(filePath, updatedContent); -} - -export function updateJestMocked(tree: Tree, filePath: string) { - const contents = tree.read(filePath, 'utf-8'); - const jestGlobalNodes = tsquery.query( - contents, - ':matches(ImportDeclaration, VariableStatement):has(Identifier[name="jest"]):has(StringLiteral[value="@jest/globals"])' - ); - - // this only applies if using jest from @jest/globals - if (jestGlobalNodes.length === 0) { - return; - } - - const updatedJestMockTypes = tsquery.replace( - contents, - 'CallExpression:has(Identifier[name="jest"]):has(Identifier[name="mocked"])', - (node: CallExpression) => { - if ( - node.arguments.length === 2 && - node.getText().startsWith('jest.mocked(') - ) { - const text = node.getText(); - // jest.mocked(someObject, true); => jest.mocked(someObject); - if (node.arguments[1].getText() === 'true') { - return text.replace(/,\s*true/g, ''); - } - // jest.mocked(someObject, false); => jest.mocked(someObject, {shallow: true}); - // opt into the new behavior unless explicitly opting out - if (node.arguments[1].getText() === 'false') { - return text.replace('false', '{shallow: true}'); - } - } - } - ); - - tree.write(filePath, updatedJestMockTypes); -} - -export default updateTestsJest29; diff --git a/packages/plugin/src/migrations/update-15-9-0/update-configs-jest-29.spec.ts b/packages/plugin/src/migrations/update-15-9-0/update-configs-jest-29.spec.ts deleted file mode 100644 index 581d6dd424580..0000000000000 --- a/packages/plugin/src/migrations/update-15-9-0/update-configs-jest-29.spec.ts +++ /dev/null @@ -1,491 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - ProjectGraph, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; - -let projectGraph: ProjectGraph; -jest.mock('@nx/devkit', () => ({ - ...jest.requireActual('@nx/devkit'), - createProjectGraphAsync: jest.fn().mockImplementation(async () => { - return projectGraph; - }), -})); - -import { updateConfigsJest29 } from './jest-29-configs'; -import { libraryGenerator } from '@nx/js'; - -describe('Nx Plugin Migration - jest 29 update configs', () => { - let tree: Tree; - - let originalEnv: string; - beforeAll(() => { - originalEnv = process.env.NX_ADD_PLUGINS; - process.env.NX_ADD_PLUGINS = 'false'; - }); - afterAll(() => { - process.env.NX_ADD_PLUGINS = originalEnv; - }); - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - afterAll(() => { - jest.resetAllMocks(); - }); - it('should update jest.config.ts', async () => { - await setup(tree, 'my-lib'); - - await updateConfigsJest29(tree); - - const actualJestConfigTs = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(actualJestConfigTs).toMatchSnapshot(); - const actualJestConfigJs = tree.read('libs/my-lib/jest.config.js', 'utf-8'); - expect(actualJestConfigJs).toMatchSnapshot(); - }); - - it('should update root preset', async () => { - await setup(tree, 'my-lib'); - await updateConfigsJest29(tree); - - const actualPreset = tree.read('jest.preset.js', 'utf-8'); - expect(actualPreset).toMatchSnapshot(); - const actualJestConfigTs = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(actualJestConfigTs).toMatchSnapshot(); - const actualJestConfigJs = tree.read('libs/my-lib/jest.config.js', 'utf-8'); - expect(actualJestConfigJs).toMatchSnapshot(); - }); - - it('should update root preset if ts-jest is preset', async () => { - await setup(tree, 'my-lib'); - tree.write( - 'jest.preset.js', - `const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, - transform: { - '^.+\\.(ts|js|html)$': 'ts-jest', - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], -}; -` - ); - - await updateConfigsJest29(tree); - - const actualPreset = tree.read('jest.preset.js', 'utf-8'); - expect(actualPreset).toMatchSnapshot(); - }); - - it('should NOT update ts-jest with no globals are preset', async () => { - await setup(tree, 'my-lib'); - tree.write( - 'jest.preset.js', - `const nxPreset = require('@nrwl/jest/preset').default; -module.exports = { - ...nxPreset, - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - transform: { - '^.+\\.(ts|js|html)$': 'ts-jest', - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'], -}; -` - ); - - await updateConfigsJest29(tree); - - const actualPreset = tree.read('jest.preset.js', 'utf-8'); - expect(actualPreset).toMatchSnapshot(); - }); - - it('should add snapshot config with no root preset', async () => { - await setup(tree, 'my-lib'); - - tree.delete('jest.preset.js'); - - await updateConfigsJest29(tree); - - const actualJestConfigTs = tree.read('libs/my-lib/jest.config.ts', 'utf-8'); - expect(actualJestConfigTs).toMatchSnapshot(); - const actualJestConfigJs = tree.read('libs/my-lib/jest.config.js', 'utf-8'); - expect(actualJestConfigJs).toMatchSnapshot(); - }); - - it('should work with multiple projects + configs', async () => { - await setup(tree, 'my-lib'); - await setup(tree, 'another-lib', projectGraph); - await updateConfigsJest29(tree); - - const actualJestConfigTs1 = tree.read( - 'libs/my-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs1).toMatchSnapshot(); - const actualJestConfigJs1 = tree.read( - 'libs/my-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs1).toMatchSnapshot(); - - const actualJestConfigTs2 = tree.read( - 'libs/another-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs2).toMatchSnapshot(); - const actualJestConfigJs2 = tree.read( - 'libs/another-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs2).toMatchSnapshot(); - }); - - it('should update globalThis.ngJest.teardown to testEnvironmentOptions ', async () => { - await setup(tree, 'jest-preset-angular'); - tree.write( - `libs/jest-preset-angular/jest.config.ts`, - `globalThis.ngJest = { - teardown: true -} - -export default { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - tree.write( - `libs/jest-preset-angular/jest.config.js`, - ` -globalThis.ngJest = { - ngcc: true, - teardown: false -} - -module.exports = { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - testEnvironmentOptions: { - blah: 123, - }, - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - await updateConfigsJest29(tree); - const jpaJestConfigTs = tree.read( - `libs/jest-preset-angular/jest.config.ts`, - 'utf-8' - ); - expect(jpaJestConfigTs).toMatchSnapshot(); - const jpaJestConfigJs = tree.read( - `libs/jest-preset-angular/jest.config.js`, - 'utf-8' - ); - expect(jpaJestConfigJs).toMatchSnapshot(); - }); - - it('should work with jest-preset-angular', async () => { - await setup(tree, 'jest-preset-angular'); - tree.write( - `libs/jest-preset-angular/jest.config.ts`, - `export default { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - tree.write( - `libs/jest-preset-angular/jest.config.js`, - `module.exports = { - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - } - }, - transform: { - '^.+.(ts|mjs|js|html)$': 'jest-preset-angular', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - await updateConfigsJest29(tree); - const jpaJestConfigTs = tree.read( - `libs/jest-preset-angular/jest.config.ts`, - 'utf-8' - ); - expect(jpaJestConfigTs).toMatchSnapshot(); - const jpaJestConfigJs = tree.read( - `libs/jest-preset-angular/jest.config.js`, - 'utf-8' - ); - expect(jpaJestConfigJs).toMatchSnapshot(); - }); - - it('should work if not using ts-jest transformer', async () => { - await setup(tree, 'no-ts-jest'); - tree.write( - `libs/no-ts-jest/jest.config.ts`, - `export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - tree.write( - `libs/no-ts-jest/jest.config.js`, - `module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', -};` - ); - - await updateConfigsJest29(tree); - const noTsJestConfigTs = tree.read( - `libs/no-ts-jest/jest.config.ts`, - 'utf-8' - ); - expect(noTsJestConfigTs).toMatchSnapshot(); - const noTsJestConfigJs = tree.read( - `libs/no-ts-jest/jest.config.js`, - 'utf-8' - ); - expect(noTsJestConfigJs).toMatchSnapshot(); - }); - - it('should work snapshotFormat is defined', async () => { - await setup(tree, 'no-ts-jest'); - tree.write( - `libs/no-ts-jest/jest.config.ts`, - `export default { - transform: { - '^.+\\\\.[tj]sx?$': 'babel-jest', - }, - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - snapshotFormat: {escapeString: false, printBasicPrototype: true} -};` - ); - tree.write( - `libs/no-ts-jest/jest.config.js`, - `module.exports = { - transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], - displayName: 'jest', - testEnvironment: 'node', - preset: '../../jest.preset.js', - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, - snapshotFormat: {escapeString: false, printBasicPrototype: true} -};` - ); - - await updateConfigsJest29(tree); - const snapshotJestConfigTs = tree.read( - 'libs/no-ts-jest/jest.config.ts', - 'utf-8' - ); - expect(snapshotJestConfigTs).toMatchSnapshot(); - const snapshotJestConfigJs = tree.read( - `libs/no-ts-jest/jest.config.js`, - 'utf-8' - ); - expect(snapshotJestConfigJs).toMatchSnapshot(); - }); - it('should be idempotent', async () => { - await setup(tree, 'my-lib'); - - await updateConfigsJest29(tree); - - const actualJestConfigTs1 = tree.read( - 'libs/my-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs1).toMatchSnapshot(); - const actualJestConfigJs1 = tree.read( - 'libs/my-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs1).toMatchSnapshot(); - - await updateConfigsJest29(tree); - - const actualJestConfigTs2 = tree.read( - 'libs/my-lib/jest.config.ts', - 'utf-8' - ); - expect(actualJestConfigTs2).toEqual(actualJestConfigTs1); - const actualJestConfigJs2 = tree.read( - 'libs/my-lib/jest.config.js', - 'utf-8' - ); - expect(actualJestConfigJs2).toEqual(actualJestConfigJs1); - }); -}); - -async function setup(tree: Tree, name: string, existingGraph?: ProjectGraph) { - await libraryGenerator(tree, { - name, - }); - const projectConfig = readProjectConfiguration(tree, name); - projectConfig.targets['test'] = { - ...projectConfig.targets['test'], - executor: '@nrwl/nx-plugin:e2e', - configurations: { - ci: { - ci: true, - }, - other: { - jestConfig: `libs/${name}/jest.config.js`, - }, - }, - }; - - updateProjectConfiguration(tree, name, projectConfig); - tree.write( - `libs/${name}/jest.config.ts`, - `/* eslint-disable */ -export default { - displayName: '${name}', - preset: '../../jest.preset.js', - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - } - }, - transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest' - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/${name}' -}; -` - ); - - tree.write( - `libs/${name}/jest.config.js`, - `module.exports = { -transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest' -}, -// I am a comment and shouldn't be removed -moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], -globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - }, - something: 'else', - abc: [1234, true, {abc: 'yes'}] - }, -/** - * Multi-line comment shouldn't be removed - */ -displayName: 'jest', -testEnvironment: 'node', -preset: '../../jest.preset.js' -}; -` - ); - - tree.write( - 'jest.config.ts', - tree - .read('jest.config.ts') - .toString() - .replace(new RegExp('@nx/jest', 'g'), '@nrwl/jest') - ); - - tree.write( - 'jest.preset.js', - tree - .read('jest.preset.js') - .toString() - .replace(new RegExp('@nx/jest', 'g'), '@nrwl/jest') - ); - - projectGraph = { - dependencies: { - ...existingGraph?.dependencies, - }, - nodes: { - ...existingGraph?.nodes, - [name]: { - name, - type: 'lib', - data: projectConfig, - } as any, - }, - }; -} diff --git a/packages/plugin/src/migrations/update-15-9-0/update-tests-jest-29.spec.ts b/packages/plugin/src/migrations/update-15-9-0/update-tests-jest-29.spec.ts deleted file mode 100644 index a8c1ed80fcfbc..0000000000000 --- a/packages/plugin/src/migrations/update-15-9-0/update-tests-jest-29.spec.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { - ProjectGraph, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; - -let projectGraph: ProjectGraph; -jest.mock('@nx/devkit', () => ({ - ...jest.requireActual('@nx/devkit'), - createProjectGraphAsync: jest - .fn() - .mockImplementation(async () => projectGraph), -})); - -import { libraryGenerator } from '@nx/js'; -import { updateTestsJest29 } from './jest-29-tests'; - -describe('Nx Plugin Migration - jest 29 mocked usage in tests', () => { - let tree: Tree; - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should not update anything if there are no tests', async () => { - await setup(tree, 'my-lib'); - const expected = tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8'); - await updateTestsJest29(tree); - expect( - tree.read('libs/my-lib/src/file-one.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/file-two.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect(tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8')).toEqual( - expected - ); - }); - it('should be idempotent', async () => { - await setup(tree, 'my-lib'); - - const expected = tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8'); - - await updateTestsJest29(tree); - - expect( - tree.read('libs/my-lib/src/file-one.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/file-two.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect(tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8')).toEqual( - expected - ); - - await updateTestsJest29(tree); - - expect( - tree.read('libs/my-lib/src/file-one.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/my-lib/src/file-two.spec.ts', 'utf-8') - ).toMatchSnapshot(); - expect(tree.read('libs/my-lib/src/lib/my-lib.spec.ts', 'utf-8')).toEqual( - expected - ); - }); -}); - -async function setup(tree: Tree, name: string) { - await libraryGenerator(tree, { - name, - }); - const projectConfig = readProjectConfiguration(tree, name); - projectConfig.targets['test'] = { - ...projectConfig.targets['test'], - configurations: { - ci: { - ci: true, - }, - other: { - jestConfig: `libs/${name}/jest.config.js`, - }, - }, - }; - - updateProjectConfiguration(tree, name, projectConfig); - - tree.write( - `libs/${name}/jest.config.js`, - `module.exports = { -transform: { - '^.+\\\\.[tj]sx?$': 'ts-jest' -}, -moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], -globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json' - } - }, -displayName: 'jest', -testEnvironment: 'node', -preset: '../../jest.preset.js' -}; - -` - ); - tree.write( - `libs/${name}/src/file-one.spec.ts`, - ` -import{ MaybeMockedDeep, MaybeMocked } from 'jest-mock'; -import {expect, jest, test} from '@jest/globals'; -import {song} from './song'; - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); - ` - ); - tree.write( - `libs/${name}/src/file-two.spec.ts`, - ` -const { MaybeMockedDeep, MaybeMocked } = require('jest-mock'); -const {expect, jest, test} = require('@jest/globals'); -const {song} = require('./song'); - -jest.mock('./song'); -jest.spyOn(console, 'log'); - -const mockedSong = jest.mocked(song, true); -// or through \`jest.Mocked\` -// const mockedSong = song as jest.Mocked; - -test('deep method is typed correctly', () => { - mockedSong.one.more.time.mockReturnValue(12); - - expect(mockedSong.one.more.time(10)).toBe(12); - expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); -}); - -test('direct usage', () => { - jest.mocked(console.log).mockImplementation(() => { - return; - }); - - console.log('one more time'); - - expect(jest.mocked(console.log, false).mock.calls).toHaveLength(1); -}); -` - ); - projectGraph = { - dependencies: {}, - nodes: { - [name]: { - name, - type: 'lib', - data: projectConfig, - } as any, - }, - }; -} diff --git a/packages/plugin/src/migrations/update-16-2-0/replace-e2e-executor.ts b/packages/plugin/src/migrations/update-16-2-0/replace-e2e-executor.ts index 8b5442d061110..7a140369a7c3a 100644 --- a/packages/plugin/src/migrations/update-16-2-0/replace-e2e-executor.ts +++ b/packages/plugin/src/migrations/update-16-2-0/replace-e2e-executor.ts @@ -5,7 +5,12 @@ import { updateProjectConfiguration, } from '@nx/devkit'; import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { NxPluginE2EExecutorOptions } from '../../executors/e2e/schema'; +import { JestExecutorOptions } from '@nx/jest/src/executors/jest/schema'; + +export interface NxPluginE2EExecutorOptions extends JestExecutorOptions { + target: string; + jestConfig: string; +} export default async function replaceE2EExecutor(tree: Tree): Promise { const projects = getProjects(tree); diff --git a/packages/react-native/migrations.json b/packages/react-native/migrations.json index 4c26d81f5b59d..02e43cfd4cc81 100644 --- a/packages/react-native/migrations.json +++ b/packages/react-native/migrations.json @@ -1,17 +1,5 @@ { "generators": { - "add-babel-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Adds babel.config.json to the hash of all tasks", - "factory": "./src/migrations/update-15-0-0/add-babel-inputs" - }, - "add-build-ios-target": { - "cli": "nx", - "version": "15.9.1-beta.0", - "description": "Add target build-ios and pod-install for react native apps", - "factory": "./src/migrations/update-15-9-1/add-build-ios-target" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -80,281 +68,6 @@ } }, "packageJsonUpdates": { - "15.0.0": { - "version": "15.0.0-beta.0", - "packages": { - "metro": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "metro-resolver": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "metro-babel-register": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "metro-config": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "metro-react-native-babel-preset": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "metro-react-native-babel-transformer": { - "version": "0.72.3", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.70.4", - "alwaysAddToPackageJson": false - }, - "@testing-library/react-native": { - "version": "11.2.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "4.0.13", - "alwaysAddToPackageJson": false - } - } - }, - "15.2.2": { - "version": "15.2.2-beta.0", - "packages": { - "react-native": { - "version": "0.70.6", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.70.6", - "alwaysAddToPackageJson": false - }, - "metro-resolver": { - "version": "0.73.3", - "alwaysAddToPackageJson": false - }, - "metro-babel-register": { - "version": "0.73.3", - "alwaysAddToPackageJson": false - }, - "metro-config": { - "version": "0.73.3", - "alwaysAddToPackageJson": false - }, - "metro-react-native-babel-preset": { - "version": "0.73.3", - "alwaysAddToPackageJson": false - }, - "metro-react-native-babel-transformer": { - "version": "0.73.3", - "alwaysAddToPackageJson": false - }, - "react-native-config": { - "version": "1.4.11", - "alwaysAddToPackageJson": false - }, - "@testing-library/react-native": { - "version": "11.5.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "5.3.0", - "alwaysAddToPackageJson": false - }, - "react-native-svg": { - "version": "13.6.0", - "alwaysAddToPackageJson": false - }, - "@babel/runtime": { - "version": "7.20.1", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli": { - "version": "9.3.2", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-android": { - "version": "9.3.1", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-ios": { - "version": "9.3.0", - "alwaysAddToPackageJson": false - }, - "@react-native-async-storage/async-storage": { - "version": "1.17.11", - "alwaysAddToPackageJson": false - } - } - }, - "15.6.2": { - "version": "15.6.2-beta.0", - "packages": { - "react-native": { - "version": "0.71.1", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.71.0", - "alwaysAddToPackageJson": false - }, - "metro-resolver": { - "version": "0.74.1", - "alwaysAddToPackageJson": false - }, - "metro-babel-register": { - "version": "0.74.1", - "alwaysAddToPackageJson": false - }, - "metro-config": { - "version": "0.74.1", - "alwaysAddToPackageJson": false - }, - "metro-react-native-babel-preset": { - "version": "0.74.1", - "alwaysAddToPackageJson": false - }, - "metro-react-native-babel-transformer": { - "version": "0.74.1", - "alwaysAddToPackageJson": false - }, - "react-native-config": { - "version": "1.4.12", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "5.4.1", - "alwaysAddToPackageJson": false - }, - "react-native-svg": { - "version": "13.7.0", - "alwaysAddToPackageJson": false - }, - "@babel/runtime": { - "version": "7.20.7", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli": { - "version": "10.1.3", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-android": { - "version": "10.1.3", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-ios": { - "version": "10.1.1", - "alwaysAddToPackageJson": false - }, - "@types/node": { - "version": "18.11.18", - "alwaysAddToPackageJson": false - }, - "react": { - "version": "18.2.0", - "alwaysAddToPackageJson": false - }, - "react-dom": { - "version": "18.2.0", - "alwaysAddToPackageJson": false - }, - "react-test-renderer": { - "version": "18.2.0", - "alwaysAddToPackageJson": false - } - } - }, - "15.7.1": { - "version": "15.7.1-beta.0", - "packages": { - "react-native": { - "version": "0.71.2", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.71.2", - "alwaysAddToPackageJson": false - }, - "react-native-config": { - "version": "1.5.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/react-native": { - "version": "11.5.2", - "alwaysAddToPackageJson": false - }, - "react-native-svg": { - "version": "13.8.0", - "alwaysAddToPackageJson": false - }, - "@babel/runtime": { - "version": "7.20.13", - "alwaysAddToPackageJson": false - } - } - }, - "15.8.3": { - "version": "15.8.3-beta.0", - "packages": { - "react-native": { - "version": "0.71.3", - "alwaysAddToPackageJson": false - }, - "@types/react-native": { - "version": "0.71.3", - "alwaysAddToPackageJson": false - }, - "@types/node": { - "version": "18.14.4", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli": { - "version": "10.2.0", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-android": { - "version": "10.2.0", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-ios": { - "version": "10.2.0", - "alwaysAddToPackageJson": false - }, - "@testing-library/jest-native": { - "version": "5.4.2", - "alwaysAddToPackageJson": false - }, - "@babel/runtime": { - "version": "7.21.0", - "alwaysAddToPackageJson": false - } - } - }, - "15.8.6": { - "version": "15.8.6-beta.0", - "packages": { - "react-native": { - "version": "0.71.4", - "alwaysAddToPackageJson": false - } - } - }, - "15.9.1": { - "version": "15.9.1-beta.0", - "packages": { - "@react-native-community/cli": { - "version": "10.2.1", - "alwaysAddToPackageJson": false - }, - "@react-native-community/cli-platform-ios": { - "version": "10.2.1", - "alwaysAddToPackageJson": false - } - } - }, "16.0.0": { "version": "16.0.0-beta.0", "packages": { diff --git a/packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.spec.ts b/packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.spec.ts deleted file mode 100644 index d98c4d1b35ab3..0000000000000 --- a/packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { Tree, readNxJson, updateNxJson } from '@nx/devkit'; -import addBabelInputs from './add-babel-inputs'; - -describe('15.0.0 migration (add-babel-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add babel.config.json to sharedGlobals', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.json', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.json", - ], - }, - } - `); - }); - - it('should add babel.config.js', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.js', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.js", - ], - }, - } - `); - }); -}); diff --git a/packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.ts b/packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.ts deleted file mode 100644 index aa7e721076fe2..0000000000000 --- a/packages/react-native/src/migrations/update-15-0-0/add-babel-inputs.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { formatFiles, Tree } from '@nx/devkit'; -import { addBabelInputs } from '@nx/js/src/utils/add-babel-inputs'; - -export default async function (tree: Tree) { - addBabelInputs(tree); - await formatFiles(tree); -} diff --git a/packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.spec.ts b/packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.spec.ts deleted file mode 100644 index 6ed42afc3e39f..0000000000000 --- a/packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { addProjectConfiguration, getProjects, Tree } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import update from './add-build-ios-target'; - -describe('add-build-ios-target', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - addProjectConfiguration(tree, 'product', { - root: 'apps/product', - sourceRoot: 'apps/product/src', - targets: { - start: { - executor: '@nrwl/react-native:start', - }, - }, - }); - }); - - it(`should update project.json with target build-ios and pod-install`, async () => { - await update(tree); - - getProjects(tree).forEach((project) => { - expect(project.targets['build-ios']).toEqual({ - executor: '@nrwl/react-native:build-ios', - outputs: ['{projectRoot}/ios/build/Build'], - options: {}, - }); - expect(project.targets['pod-install']).toEqual({ - executor: '@nrwl/react-native:pod-install', - options: {}, - }); - }); - }); -}); diff --git a/packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.ts b/packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.ts deleted file mode 100644 index b80a1bfb8465d..0000000000000 --- a/packages/react-native/src/migrations/update-15-9-1/add-build-ios-target.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - Tree, - formatFiles, - getProjects, - updateProjectConfiguration, -} from '@nx/devkit'; - -/** - * Add build-ios target for react-native - */ -export default async function update(tree: Tree) { - const projects = getProjects(tree); - - for (const [name, config] of projects.entries()) { - if (config.targets?.['start']?.executor === '@nrwl/react-native:start') { - if (!config.targets['build-ios']) { - config.targets['build-ios'] = { - executor: '@nrwl/react-native:build-ios', - outputs: ['{projectRoot}/ios/build/Build'], - options: {}, - }; - } - if (!config.targets['pod-install']) { - config.targets['pod-install'] = { - executor: '@nrwl/react-native:pod-install', - options: {}, - }; - } - updateProjectConfiguration(tree, name, config); - } - } - - await formatFiles(tree); -} diff --git a/packages/react/migrations.json b/packages/react/migrations.json index 16efe10c5b4fe..6dab83a5d30c4 100644 --- a/packages/react/migrations.json +++ b/packages/react/migrations.json @@ -1,23 +1,5 @@ { "generators": { - "update-rollup-executor": { - "cli": "nx", - "version": "15.3.0-beta.0", - "description": "Update projects using @nrwl/web:rollup to @nrwl/rollup:rollup for build.", - "factory": "./src/migrations/update-15-3-0/update-rollup-executor" - }, - "install-webpack-rollup-dependencies": { - "cli": "nx", - "version": "15.3.0-beta.0", - "description": "Install new dependencies for React projects using Webpack or Rollup.", - "factory": "./src/migrations/update-15-3-0/install-webpack-rollup-dependencies" - }, - "react-webpack-config-setup": { - "cli": "nx", - "version": "15.6.3-beta.0", - "description": "Creates or updates webpack.config.js file with the new options for webpack.", - "factory": "./src/migrations/update-15-6-3/webpack-config-setup" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -62,148 +44,6 @@ } }, "packageJsonUpdates": { - "15.2.2-beta.0": { - "version": "15.2.2-beta.0", - "packages": { - "@types/react": { - "version": "18.0.25", - "alwaysAddToPackageJson": false - }, - "@types/react-dom": { - "version": "18.0.9", - "alwaysAddToPackageJson": false - }, - "@types/node": { - "version": "18.11.9", - "alwaysAddToPackageJson": false - }, - "styled-components": { - "version": "5.3.6", - "alwaysAddToPackageJson": false - }, - "@emotion/styled": { - "version": "11.10.5", - "alwaysAddToPackageJson": false - }, - "@emotion/react": { - "version": "11.10.5", - "alwaysAddToPackageJson": false - }, - "@emotion/babel-plugin": { - "version": "11.10.5", - "alwaysAddToPackageJson": false - }, - "styled-jsx": { - "version": "5.1.0", - "alwaysAddToPackageJson": false - }, - "react-router-dom": { - "version": "6.4.3", - "alwaysAddToPackageJson": false - }, - "@reduxjs/toolkit": { - "version": "1.9.0", - "alwaysAddToPackageJson": false - }, - "react-redux": { - "version": "8.0.5", - "alwaysAddToPackageJson": false - }, - "eslint-plugin-react": { - "version": "7.31.11", - "alwaysAddToPackageJson": false - }, - "postcss": { - "version": "8.4.19", - "alwaysAddToPackageJson": false - }, - "tailwindcss": { - "version": "3.2.4", - "alwaysAddToPackageJson": false - }, - "autoprefixer": { - "version": "10.4.13", - "alwaysAddToPackageJson": false - }, - "@types/express": { - "version": "4.17.14", - "alwaysAddToPackageJson": false - } - } - }, - "15.8.0": { - "version": "15.8.0-beta.0", - "packages": { - "@types/react": { - "version": "18.0.28", - "alwaysAddToPackageJson": false - }, - "@types/react-dom": { - "version": "18.0.11", - "alwaysAddToPackageJson": false - }, - "@types/node": { - "version": "18.14.2", - "alwaysAddToPackageJson": false - }, - "@emotion/styled": { - "version": "11.10.6", - "alwaysAddToPackageJson": false - }, - "@emotion/react": { - "version": "11.10.6", - "alwaysAddToPackageJson": false - }, - "@emotion/babel-plugin": { - "version": "11.10.6", - "alwaysAddToPackageJson": false - }, - "styled-jsx": { - "version": "5.1.2", - "alwaysAddToPackageJson": false - }, - "react-router-dom": { - "version": "6.8.1", - "alwaysAddToPackageJson": false - }, - "@testing-library/react": { - "version": "14.0.0", - "alwaysAddToPackageJson": false - }, - "@reduxjs/toolkit": { - "version": "1.9.3", - "alwaysAddToPackageJson": false - }, - "eslint-plugin-import": { - "version": "2.27.5", - "alwaysAddToPackageJson": false - }, - "eslint-plugin-jsx-a11y": { - "version": "6.7.1", - "alwaysAddToPackageJson": false - }, - "eslint-plugin-react": { - "version": "7.32.2", - "alwaysAddToPackageJson": false - }, - "postcss": { - "version": "8.4.21", - "alwaysAddToPackageJson": false - }, - "tailwindcss": { - "version": "3.2.7", - "alwaysAddToPackageJson": false - }, - "@types/express": { - "version": "4.17.17", - "alwaysAddToPackageJson": false - }, - "less": { - "version": "4.1.3", - "alwaysAddToPackageJson": false - } - } - }, "16.3.0": { "version": "16.3.0-beta.2", "packages": { diff --git a/packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.spec.ts b/packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.spec.ts deleted file mode 100644 index dd268dbba06b0..0000000000000 --- a/packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { addProjectConfiguration, readJson } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { installWebpackRollupDependencies } from './install-webpack-rollup-dependencies'; - -describe('installWebpackRollupDependencies', () => { - it('should install packages if webpack is used', async () => { - const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - build: { executor: '@nrwl/webpack:webpack' }, - }, - }); - - await installWebpackRollupDependencies(tree); - - expect(readJson(tree, 'package.json')).toMatchObject({ - devDependencies: { - webpack: '^5.75.0', - }, - }); - }); - - it('should install packages if rollup is used', async () => { - const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - build: { executor: '@nrwl/rollup:rollup' }, - }, - }); - - await installWebpackRollupDependencies(tree); - - expect(readJson(tree, 'package.json')).toMatchObject({ - devDependencies: { - webpack: '^5.75.0', - }, - }); - }); - - it('should not install packages if neither webpack nor rollup are used', async () => { - const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - build: { executor: '@nrwl/vite:build' }, - }, - }); - - await installWebpackRollupDependencies(tree); - - expect(readJson(tree, 'package.json')).not.toMatchObject({ - devDependencies: { - webpack: '^5.75.0', - }, - }); - }); -}); diff --git a/packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.ts b/packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.ts deleted file mode 100644 index 0730af4b906f1..0000000000000 --- a/packages/react/src/migrations/update-15-3-0/install-webpack-rollup-dependencies.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { addDependenciesToPackageJson, getProjects, Tree } from '@nx/devkit'; -import { nxVersion } from '../../utils/versions'; -export function installWebpackRollupDependencies(tree: Tree) { - const projects = getProjects(tree); - let shouldInstall = false; - - for (const [, project] of projects) { - if ( - project.targets?.build?.executor === '@nrwl/webpack:webpack' || - project.targets?.build?.executor === '@nrwl/rollup:rollup' || - project.targets?.build?.executor === '@nrwl/web:rollup' - ) { - shouldInstall = true; - break; - } - } - - if (shouldInstall) { - // These were previously dependencies of `@nrwl/react` but we've removed them - // to accommodate different bundlers and test runners. - return addDependenciesToPackageJson( - tree, - {}, - { - '@babel/preset-react': '^7.14.5', - '@pmmmwh/react-refresh-webpack-plugin': '^0.5.7', - '@svgr/webpack': '^6.1.2', - 'css-loader': '^6.4.0', - 'react-refresh': '^0.10.0', - 'style-loader': '^3.3.0', - stylus: '^0.55.0', - 'stylus-loader': '^7.1.0', - 'url-loader': '^4.1.1', - webpack: '^5.75.0', - 'webpack-merge': '^5.8.0', - '@nrwl/webpack': nxVersion, - } - ); - } -} - -export default installWebpackRollupDependencies; diff --git a/packages/react/src/migrations/update-15-3-0/update-rollup-executor.spec.ts b/packages/react/src/migrations/update-15-3-0/update-rollup-executor.spec.ts deleted file mode 100644 index 2657520253b44..0000000000000 --- a/packages/react/src/migrations/update-15-3-0/update-rollup-executor.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - addProjectConfiguration, - ProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { updateRollupExecutor } from './update-rollup-executor'; - -describe('updateRollupExecutor', () => { - it('should migrate projects using @nrwl/web:rollup to @nrwl/rollup:rollup', async () => { - const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - addProjectConfiguration(tree, 'proj1', { - root: 'proj1', - targets: { - build: { executor: '@nrwl/esbuild:esbuild' }, - }, - }); - addProjectConfiguration(tree, 'proj2', { - root: 'proj2', - targets: { - build: { executor: '@nrwl/web:rollup' }, - }, - }); - addProjectConfiguration(tree, 'proj3', { - root: 'proj3', - targets: { - build: { executor: '@nrwl/webpack:webpack' }, - }, - }); - - updateRollupExecutor(tree); - - expect(readProjectConfiguration(tree, 'proj1')).toMatchObject({ - targets: { - build: { executor: '@nrwl/esbuild:esbuild' }, - }, - }); - expect(readProjectConfiguration(tree, 'proj2')).toMatchObject({ - targets: { - build: { executor: '@nrwl/rollup:rollup' }, - }, - }); - expect(readProjectConfiguration(tree, 'proj3')).toMatchObject({ - targets: { - build: { executor: '@nrwl/webpack:webpack' }, - }, - }); - }); -}); diff --git a/packages/react/src/migrations/update-15-3-0/update-rollup-executor.ts b/packages/react/src/migrations/update-15-3-0/update-rollup-executor.ts deleted file mode 100644 index 3c0c6c18a1b62..0000000000000 --- a/packages/react/src/migrations/update-15-3-0/update-rollup-executor.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { getProjects, Tree, updateProjectConfiguration } from '@nx/devkit'; - -export function updateRollupExecutor(tree: Tree) { - const projects = getProjects(tree); - - for (const [name, project] of projects) { - if (project.targets?.build?.executor === '@nrwl/web:rollup') { - project.targets.build.executor = '@nrwl/rollup:rollup'; - updateProjectConfiguration(tree, name, project); - } - } -} - -export default updateRollupExecutor; diff --git a/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap b/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap deleted file mode 100644 index d75a10b8058ac..0000000000000 --- a/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap +++ /dev/null @@ -1,77 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 1`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); -const { withReact } = require('@nrwl/react'); - -// Nx plugins for webpack. -module.exports = composePlugins( - withNx(), - withReact(), - (config, { options, context }) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; - } -); -" -`; - -exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 2`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); -const { withReact } = require('@nrwl/react'); - -// Nx plugins for webpack. -module.exports = composePlugins( - withNx(), - withReact(), - (config, { options, context }) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; - } -); -" -`; - -exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 3`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); -const { withReact } = require('@nrwl/react'); - -// Nx plugins for webpack. -module.exports = composePlugins( - withNx(), - withReact(), - (config, { options, context }) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; - } -); -" -`; - -exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 4`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); -const { withReact } = require('@nrwl/react'); - -// Nx plugins for webpack. -module.exports = composePlugins( - withNx(), - withReact(), - (config, { options, context }) => { - // Note: This was added by an Nx migration. - // You should consider inlining the logic into this file. - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return require('./webpack.something.old.ts')(config, context); - } -); -" -`; diff --git a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts b/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts deleted file mode 100644 index 1720c1f2dad33..0000000000000 --- a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts +++ /dev/null @@ -1,297 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import webpackConfigSetup from './webpack-config-setup'; - -describe('15.6.3 migration (setup webpack.config file for React apps)', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should create webpack.config.js for React projects only', async () => { - addProjectConfiguration(tree, 'react1', { - root: 'apps/react1', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/react1/src/main.tsx', - webpackConfig: '@nrwl/react/plugins/webpack', - }, - }, - }, - }); - addProjectConfiguration(tree, 'react2', { - root: 'apps/react2', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/react2/src/main.tsx', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'react3', { - root: 'apps/react3', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: '@nrwl/react/plugins/webpack', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'react4', { - root: 'apps/react4', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/react4/src/main.tsx', - webpackConfig: 'apps/react4/webpack.something.ts', - }, - }, - }, - }); - tree.write('apps/react4/webpack.something.ts', 'some content'); - - await webpackConfigSetup(tree); - - expect( - tree.read('apps/react1/webpack.config.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/react2/webpack.config.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/react3/webpack.config.js', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read('apps/react4/webpack.something.ts', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read('apps/react4/webpack.something.old.ts', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - }); - - it('should ignore non-react projects or isolatedConfig', async () => { - addProjectConfiguration(tree, 'app4', { - root: 'apps/app4', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: 'some/random/path/webpack.something.ts', - }, - }, - }, - }); - tree.write('some/random/path/webpack.something.ts', 'some content'); - - addProjectConfiguration(tree, 'app5', { - root: 'apps/app5', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - isolatedConfig: true, - }, - }, - }, - }); - - addProjectConfiguration(tree, 'app6', { - root: 'apps/app6', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/app6/src/main.ts', - }, - }, - }, - }); - - await webpackConfigSetup(tree); - - expect( - tree.read('some/random/path/webpack.something.ts', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - expect( - tree.exists('some/random/path/webpack.something.old.ts') - ).toBeFalsy(); - expect(tree.exists('apps/app5/webpack.config.js')).toBeFalsy(); - expect(tree.exists('apps/app6/webpack.config.js')).toBeFalsy(); - }); - - it('should update the project configuration - executor options', async () => { - addProjectConfiguration(tree, 'react1', { - root: 'apps/react1', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/react1/src/main.tsx', - webpackConfig: '@nrwl/react/plugins/webpack', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'react2', { - root: 'apps/react2', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/react2/src/main.tsx', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'react3', { - root: 'apps/react3', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: '@nrwl/react/plugins/webpack', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'react4', { - root: 'apps/react4', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/react4/src/main.tsx', - webpackConfig: 'apps/react4/webpack.something.ts', - }, - }, - }, - }); - tree.write('apps/react4/webpack.something.ts', 'some content'); - - await webpackConfigSetup(tree); - - expect( - readProjectConfiguration(tree, 'react1').targets.build.options - .webpackConfig - ).toBe('apps/react1/webpack.config.js'); - expect( - readProjectConfiguration(tree, 'react2').targets.custom.options - .webpackConfig - ).toBe('apps/react2/webpack.config.js'); - - expect( - readProjectConfiguration(tree, 'react3').targets.custom.options - .webpackConfig - ).toBe('apps/react3/webpack.config.js'); - - expect( - readProjectConfiguration(tree, 'react4').targets.custom.options - .webpackConfig - ).toBe('apps/react4/webpack.something.ts'); - - expect( - readProjectConfiguration(tree, 'react1').targets.build.options - .isolatedConfig - ).toBeTruthy(); - expect( - readProjectConfiguration(tree, 'react2').targets.custom.options - .isolatedConfig - ).toBeTruthy(); - - expect( - readProjectConfiguration(tree, 'react3').targets.custom.options - .isolatedConfig - ).toBeTruthy(); - - expect( - readProjectConfiguration(tree, 'react4').targets.custom.options - .isolatedConfig - ).toBeTruthy(); - }); - - it('should migrate configurations (dev, prod, etc.) with webpackConfig but ignore ones without it', async () => { - addProjectConfiguration(tree, 'reactapp', { - root: 'apps/reactapp', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/reactapp/src/main.tsx', - webpackConfig: 'apps/reactapp/webpack.config.js', - }, - configurations: { - foo: {}, - bar: { - webpackConfig: 'apps/reactapp/webpack.config.bar.js', - }, - }, - }, - }, - }); - tree.write('apps/reactapp/webpack.config.js', 'default'); - tree.write('apps/reactapp/webpack.config.bar.js', 'bar'); - - addProjectConfiguration(tree, 'alreadymigrated', { - root: 'apps/alreadymigrated', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - isolatedConfig: true, - main: 'apps/alreadymigrated/src/main.tsx', - webpackConfig: 'apps/alreadymigrated/webpack.config.js', - }, - configurations: { - foo: {}, - bar: { - webpackConfig: 'apps/alreadymigrated/webpack.config.bar.js', - }, - }, - }, - }, - }); - tree.write('apps/alreadymigrated/webpack.config.js', 'default'); - tree.write('apps/alreadymigrated/webpack.config.bar.js', 'bar'); - - await webpackConfigSetup(tree); - - expect(tree.read('apps/reactapp/webpack.config.old.js', 'utf-8')).toContain( - 'default' - ); - expect( - tree.read('apps/reactapp/webpack.config.bar.old.js', 'utf-8') - ).toContain('bar'); - - expect( - tree.read('apps/alreadymigrated/webpack.config.js', 'utf-8') - ).toContain('default'); - expect( - tree.read('apps/alreadymigrated/webpack.config.bar.js', 'utf-8') - ).toContain('bar'); - expect( - tree.exists('apps/alreadymigrated/webpack.config.old.js') - ).toBeFalsy(); - expect( - tree.exists('apps/alreadymigrated/webpack.config.bar.old.js') - ).toBeFalsy(); - }); -}); diff --git a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts b/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts deleted file mode 100644 index 474104ac5ef97..0000000000000 --- a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { - formatFiles, - logger, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { basename } from 'path'; -import type { WebpackExecutorOptions } from '@nx/webpack'; - -export default async function (tree: Tree) { - // Since projects can have multiple configurations, we need to know if the default options - // need to be migrated or not. If so then the subsequent configurations with `webpackConfig` also need to be. - const defaultOptionsUpdated = new Set(); - forEachExecutorOptions( - tree, - '@nrwl/webpack:webpack', - (options, projectName, targetName, configurationName) => { - const projectConfiguration = readProjectConfiguration(tree, projectName); - const defaultOptions = projectConfiguration.targets[targetName].options; - const defaultWasUpdated = defaultOptionsUpdated.has(projectName); - - // If default was not updated (for different configurations), we don't do anything - // If isolatedConfig is set, we don't need to do anything - // If it is NOT React, we don't need to do anything - if ( - !defaultWasUpdated && - (defaultOptions?.['isolatedConfig'] || - !( - defaultOptions?.['main']?.match(/main\.(t|j)sx$/) || - defaultOptions?.['webpackConfig'] === '@nrwl/react/plugins/webpack' - )) - ) { - return; - } - defaultOptionsUpdated.add(projectName); - - // If this is not the default options (e.g. for development, production, or something custom), - // then skip it unless it specifically configures a webpackConfig file - if (configurationName && !options?.webpackConfig) { - return; - } - - // If webpackConfig is set, update it with the new options - // If webpackConfig is not set, we need to create a new - // webpack.config.js file and set the path to it in the - // executor options - - if ( - options?.['webpackConfig'] && - options['webpackConfig'] !== '@nrwl/react/plugins/webpack' - ) { - let oldName = options['webpackConfig']; - if (options['webpackConfig'].endsWith('.js')) { - oldName = options['webpackConfig'].replace('.js', '.old.js'); - } - if (options['webpackConfig'].endsWith('.ts')) { - oldName = options['webpackConfig'].replace('.ts', '.old.ts'); - } - - renameFile(tree, options['webpackConfig'], oldName); - - const justTheFileName = basename(oldName); - tree.write( - options['webpackConfig'], - ` - const { composePlugins, withNx } = require('@nrwl/webpack'); - const { withReact } = require('@nrwl/react'); - - // Nx plugins for webpack. - module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { - // Note: This was added by an Nx migration. - // You should consider inlining the logic into this file. - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return require('./${justTheFileName}')(config, context); - }); - ` - ); - - options['isolatedConfig'] = true; - - projectConfiguration.targets[targetName][ - configurationName ?? 'options' - ] = options; - updateProjectConfiguration(tree, projectName, projectConfiguration); - - logger.info( - ` - ${options['webpackConfig']} has been renamed to ${oldName} and a new ${options['webpackConfig']} - has been created for your project ${projectName}. - You should consider inlining the logic from ${oldName} into ${options['webpackConfig']}. - You can read our guide on how to do this here: - - https://nx.dev/recipes/webpack/webpack-config-setup - ` - ); - } else { - const projectConfiguration = readProjectConfiguration( - tree, - projectName - ); - - if (!options) { - options = {} as WebpackExecutorOptions; - } - - options[ - 'webpackConfig' - ] = `${projectConfiguration.root}/webpack.config.js`; - options['isolatedConfig'] = true; - - tree.write( - options['webpackConfig'], - ` - const { composePlugins, withNx } = require('@nrwl/webpack'); - const { withReact } = require('@nrwl/react'); - - // Nx plugins for webpack. - module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; - }); - ` - ); - - projectConfiguration.targets[targetName].options = options; - updateProjectConfiguration(tree, projectName, projectConfiguration); - } - } - ); - - await formatFiles(tree); -} - -function renameFile(tree: Tree, from: string, to: string) { - const buffer = tree.read(from); - if (!buffer) { - return; - } - tree.write(to, buffer); - tree.delete(from); -} diff --git a/packages/rollup/migrations.json b/packages/rollup/migrations.json index 0c16f35a64e8e..fb636fa151b6f 100644 --- a/packages/rollup/migrations.json +++ b/packages/rollup/migrations.json @@ -1,11 +1,5 @@ { "generators": { - "add-babel-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Adds babel.config.json to the hash of all tasks", - "factory": "./src/migrations/update-15-0-0/add-babel-inputs" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", diff --git a/packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.spec.ts b/packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.spec.ts deleted file mode 100644 index 3ac51f6d23033..0000000000000 --- a/packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { readNxJson, Tree, updateNxJson } from '@nx/devkit'; -import addBabelInputs from './add-babel-inputs'; - -describe('15.0.0 migration (add-babel-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add babel.config.json to sharedGlobals', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.json', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.json", - ], - }, - } - `); - }); - - it('should add babel.config.js', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.js', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.js", - ], - }, - } - `); - }); -}); diff --git a/packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.ts b/packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.ts deleted file mode 100644 index aa7e721076fe2..0000000000000 --- a/packages/rollup/src/migrations/update-15-0-0/add-babel-inputs.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { formatFiles, Tree } from '@nx/devkit'; -import { addBabelInputs } from '@nx/js/src/utils/add-babel-inputs'; - -export default async function (tree: Tree) { - addBabelInputs(tree); - await formatFiles(tree); -} diff --git a/packages/storybook/migrations.json b/packages/storybook/migrations.json index 49e94ec475a97..e27a9fcca26e5 100644 --- a/packages/storybook/migrations.json +++ b/packages/storybook/migrations.json @@ -1,29 +1,5 @@ { "generators": { - "update-15.0.8-add-storybook-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Stop hashing storybook config files and story files for build targets and dependent tasks", - "factory": "./src/migrations/update-15-0-0/add-storybook-inputs" - }, - "update-15.4.6": { - "cli": "nx", - "version": "15.4.6-beta.0", - "description": "Refactor the Storybook target options", - "factory": "./src/migrations/update-15-4-6/refactor-executor-options" - }, - "update-15-5-3": { - "cli": "nx", - "version": "15.5.3-beta.0", - "description": "Add @nrwl/webpack if it is missing and is used.", - "factory": "./src/migrations/update-15-5-3/ensure-webpack-package" - }, - "update-15-7-0": { - "cli": "nx", - "version": "15.7.0-beta.0", - "description": "Add @storybook/addon-essentials to all project-level configs and attempt to remove root config.", - "factory": "./src/migrations/update-15-7-0/add-addon-essentials-to-all" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -877,93 +853,6 @@ } } }, - "15.5.2": { - "version": "15.5.2-beta.0", - "packages": { - "@storybook/react-native": { - "version": "^6.0.1-beta.11", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-actions": { - "version": "^6.0.1-beta.11", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-backgrounds": { - "version": "^6.0.1-beta.11", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-controls": { - "version": "^6.0.1-beta.11", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-notes": { - "version": "^6.0.1-beta.11", - "alwaysAddToPackageJson": false - } - } - }, - "15.4.3": { - "version": "15.4.3-beta.1", - "packages": { - "@storybook/core-server": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/angular": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/react": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/web": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-essentials": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/builder-webpack5": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/manager-webpack5": { - "version": "^6.5.15", - "alwaysAddToPackageJson": false - }, - "@storybook/builder-vite": { - "version": "^0.2.6", - "alwaysAddToPackageJson": false - } - } - }, - "15.1.1": { - "version": "15.1.1-beta.0", - "packages": { - "@storybook/react-native": { - "version": "^6.0.1-beta.9", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-actions": { - "version": "^6.0.1-beta.9", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-backgrounds": { - "version": "^6.0.1-beta.9", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-controls": { - "version": "^6.0.1-beta.9", - "alwaysAddToPackageJson": false - }, - "@storybook/addon-ondevice-notes": { - "version": "^6.0.1-beta.9", - "alwaysAddToPackageJson": false - } - } - }, "18.2.0": { "version": "18.2.0-beta.1", "packages": { diff --git a/packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.spec.ts b/packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.spec.ts deleted file mode 100644 index be6df9dfea0f3..0000000000000 --- a/packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.spec.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readNxJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import addStorybookInputs from './add-storybook-inputs'; - -describe('15.0.0 migration (add-storybook-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add inputs configuration for storybook targets', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - 'build-storybook': { - executor: '@nrwl/storybook:build', - options: {}, - }, - 'build-storybook2': { - executor: '@nrwl/storybook:build', - options: {}, - }, - notStorybook: { - executor: 'nx:run-commands', - }, - }, - }); - tree.write('.storybook/main.js', ''); - - await addStorybookInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - "!{projectRoot}/.storybook/**/*", - "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", - ], - "sharedGlobals": [], - }, - "targetDefaults": { - "build-storybook": { - "inputs": [ - "default", - "^production", - "{workspaceRoot}/.storybook/**/*", - ], - }, - "build-storybook2": { - "inputs": [ - "default", - "^production", - "{workspaceRoot}/.storybook/**/*", - ], - }, - }, - } - `); - }); - - it('should add inputs configuration for angular storybook targets', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - addProjectConfiguration(tree, 'proj', { - root: 'proj', - targets: { - 'build-storybook': { - executor: '@storybook/angular:build-storybook', - options: {}, - }, - 'build-storybook2': { - executor: '@storybook/angular:build-storybook', - options: {}, - }, - notStorybook: { - executor: 'nx:run-commands', - }, - }, - }); - tree.write('.storybook/main.js', ''); - - await addStorybookInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - "!{projectRoot}/.storybook/**/*", - "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", - ], - "sharedGlobals": [], - }, - "targetDefaults": { - "build-storybook": { - "inputs": [ - "default", - "^production", - "{workspaceRoot}/.storybook/**/*", - ], - }, - "build-storybook2": { - "inputs": [ - "default", - "^production", - "{workspaceRoot}/.storybook/**/*", - ], - }, - }, - } - `); - }); -}); diff --git a/packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.ts b/packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.ts deleted file mode 100644 index ccb297a0b5f64..0000000000000 --- a/packages/storybook/src/migrations/update-15-0-0/add-storybook-inputs.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { formatFiles, readNxJson, Tree, updateNxJson } from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; - -export default async function (tree: Tree) { - const nxJson = readNxJson(tree); - - const storybookTargets = getStorybookBuildTargets(tree); - const hasProductionFileset = !!nxJson.namedInputs?.production; - - if (storybookTargets.size > 0 && hasProductionFileset) { - const productionFileset = new Set(nxJson.namedInputs.production); - for (const exclusion of [ - '!{projectRoot}/.storybook/**/*', - '!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)', - ]) { - productionFileset.add(exclusion); - } - nxJson.namedInputs.production = Array.from(productionFileset); - } - - for (const targetName of storybookTargets) { - nxJson.targetDefaults ??= {}; - const storybookTargetDefaults = (nxJson.targetDefaults[targetName] ??= {}); - - storybookTargetDefaults.inputs ??= [ - 'default', - hasProductionFileset ? '^production' : '^default', - ...(tree.exists('.storybook') ? ['{workspaceRoot}/.storybook/**/*'] : []), - ]; - } - - updateNxJson(tree, nxJson); - - await formatFiles(tree); -} - -function getStorybookBuildTargets(tree: Tree) { - const storybookBuildTargets = new Set(); - forEachExecutorOptions(tree, '@nrwl/storybook:build', (_, __, target) => { - storybookBuildTargets.add(target); - }); - forEachExecutorOptions( - tree, - '@storybook/angular:build-storybook', - (_, __, target) => { - storybookBuildTargets.add(target); - } - ); - return storybookBuildTargets; -} diff --git a/packages/storybook/src/migrations/update-15-4-6/__snapshots__/refactor-executor-options.spec.ts.snap b/packages/storybook/src/migrations/update-15-4-6/__snapshots__/refactor-executor-options.spec.ts.snap deleted file mode 100644 index 5c298407a95bd..0000000000000 --- a/packages/storybook/src/migrations/update-15-4-6/__snapshots__/refactor-executor-options.spec.ts.snap +++ /dev/null @@ -1,1093 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`update the executor options to match the new schema for non-angular projects should update the target options 1`] = ` -Map { - "main-vite-new" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "main-vite-new", - "projectType": "application", - "root": "apps/main-vite-new", - "sourceRoot": "apps/main-vite-new/src", - "tags": [], - "targets": { - "build": { - "configurations": { - "development": { - "mode": "development", - }, - "production": { - "mode": "production", - }, - }, - "defaultConfiguration": "production", - "executor": "@nrwl/vite:build", - "options": { - "outputPath": "dist/apps/main-vite-new", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "build-storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:build", - "options": { - "configDir": "apps/main-vite-new/.storybook", - "outputDir": "dist/storybook/main-vite-new", - "uiFramework": "@storybook/react", - }, - "outputs": [ - "{options.outputDir}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-vite-new/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "serve": { - "configurations": { - "development": { - "buildTarget": "main-vite-new:build:development", - "hmr": true, - }, - "production": { - "buildTarget": "main-vite-new:build:production", - "hmr": false, - }, - }, - "defaultConfiguration": "development", - "executor": "@nrwl/vite:dev-server", - "options": { - "buildTarget": "main-vite-new:build", - }, - }, - "storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:storybook", - "options": { - "configDir": "apps/main-vite-new/.storybook", - "port": 4400, - "uiFramework": "@storybook/react", - }, - }, - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/apps/main-vite-new", - }, - "outputs": [ - "coverage/apps/main-vite-new", - ], - }, - }, - }, - "main-vite" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "main-vite", - "projectType": "application", - "root": "apps/main-vite", - "sourceRoot": "apps/main-vite/src", - "tags": [], - "targets": { - "build": { - "configurations": { - "development": { - "mode": "development", - }, - "production": { - "mode": "production", - }, - }, - "defaultConfiguration": "production", - "executor": "@nrwl/vite:build", - "options": { - "outputPath": "dist/apps/main-vite", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "build-storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:build", - "options": { - "configDir": "apps/main-vite/.storybook", - "outputDir": "dist/storybook/main-vite", - "uiFramework": "@storybook/react", - }, - "outputs": [ - "{options.outputDir}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-vite/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "serve": { - "configurations": { - "development": { - "buildTarget": "main-vite:build:development", - "hmr": true, - }, - "production": { - "buildTarget": "main-vite:build:production", - "hmr": false, - }, - }, - "defaultConfiguration": "development", - "executor": "@nrwl/vite:dev-server", - "options": { - "buildTarget": "main-vite:build", - }, - }, - "storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:storybook", - "options": { - "configDir": "apps/main-vite/.storybook", - "port": 4400, - "uiFramework": "@storybook/react", - }, - }, - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/apps/main-vite", - }, - "outputs": [ - "coverage/apps/main-vite", - ], - }, - }, - }, - "main-vite-e2e" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [ - "main-vite", - ], - "name": "main-vite-e2e", - "projectType": "application", - "root": "apps/main-vite-e2e", - "sourceRoot": "apps/main-vite-e2e/src", - "tags": [], - "targets": { - "e2e": { - "configurations": { - "production": { - "devServerTarget": "main-vite:serve:production", - }, - }, - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/main-vite-e2e/cypress.config.ts", - "devServerTarget": "main-vite:serve:development", - "testingType": "e2e", - }, - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-vite-e2e/**/*.{js,ts}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - }, - }, - "main-vite-ts" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "main-vite-ts", - "projectType": "application", - "root": "apps/main-vite-ts", - "sourceRoot": "apps/main-vite-ts/src", - "tags": [], - "targets": { - "build": { - "configurations": { - "development": { - "mode": "development", - }, - "production": { - "mode": "production", - }, - }, - "defaultConfiguration": "production", - "executor": "@nrwl/vite:build", - "options": { - "outputPath": "dist/apps/main-vite-ts", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "build-storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:build", - "options": { - "configDir": "apps/main-vite-ts/.storybook", - "outputDir": "dist/storybook/main-vite-ts", - "uiFramework": "@storybook/react", - }, - "outputs": [ - "{options.outputDir}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-vite-ts/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "serve": { - "configurations": { - "development": { - "buildTarget": "main-vite-ts:build:development", - "hmr": true, - }, - "production": { - "buildTarget": "main-vite-ts:build:production", - "hmr": false, - }, - }, - "defaultConfiguration": "development", - "executor": "@nrwl/vite:dev-server", - "options": { - "buildTarget": "main-vite-ts:build", - }, - }, - "storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:storybook", - "options": { - "configDir": "apps/main-vite-ts/.storybook", - "port": 4400, - "uiFramework": "@storybook/react", - }, - }, - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/apps/main-vite-ts", - }, - "outputs": [ - "coverage/apps/main-vite-ts", - ], - }, - }, - }, - "main-vite-ts-e2e" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [ - "main-vite-ts", - ], - "name": "main-vite-ts-e2e", - "projectType": "application", - "root": "apps/main-vite-ts-e2e", - "sourceRoot": "apps/main-vite-ts-e2e/src", - "tags": [], - "targets": { - "e2e": { - "configurations": { - "production": { - "devServerTarget": "main-vite-ts:serve:production", - }, - }, - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/main-vite-ts-e2e/cypress.config.ts", - "devServerTarget": "main-vite-ts:serve:development", - "testingType": "e2e", - }, - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-vite-ts-e2e/**/*.{js,ts}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - }, - }, - "main-webpack" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "main-webpack", - "projectType": "application", - "root": "apps/main-webpack", - "sourceRoot": "apps/main-webpack/src", - "tags": [], - "targets": { - "build": { - "configurations": { - "development": { - "extractLicenses": false, - "optimization": false, - "sourceMap": true, - "vendorChunk": true, - }, - "production": { - "extractLicenses": true, - "fileReplacements": [ - { - "replace": "apps/main-webpack/src/environments/environment.ts", - "with": "apps/main-webpack/src/environments/environment.prod.ts", - }, - ], - "namedChunks": false, - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "vendorChunk": false, - }, - }, - "defaultConfiguration": "production", - "executor": "@nrwl/webpack:webpack", - "options": { - "assets": [ - "apps/main-webpack/src/favicon.ico", - "apps/main-webpack/src/assets", - ], - "baseHref": "/", - "compiler": "babel", - "index": "apps/main-webpack/src/index.html", - "main": "apps/main-webpack/src/main.tsx", - "outputPath": "dist/apps/main-webpack", - "polyfills": "apps/main-webpack/src/polyfills.ts", - "scripts": [], - "styles": [ - "apps/main-webpack/src/styles.css", - ], - "tsConfig": "apps/main-webpack/tsconfig.app.json", - "webpackConfig": "@nrwl/react/plugins/webpack", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "build-storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:build", - "options": { - "configDir": "apps/main-webpack/.storybook", - "outputDir": "dist/storybook/main-webpack", - "uiFramework": "@storybook/react", - }, - "outputs": [ - "{options.outputDir}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-webpack/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "serve": { - "configurations": { - "development": { - "buildTarget": "main-webpack:build:development", - }, - "production": { - "buildTarget": "main-webpack:build:production", - "hmr": false, - }, - }, - "defaultConfiguration": "development", - "executor": "@nrwl/webpack:dev-server", - "options": { - "buildTarget": "main-webpack:build", - "hmr": true, - }, - }, - "storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:storybook", - "options": { - "configDir": "apps/main-webpack/.storybook", - "port": 4400, - "uiFramework": "@storybook/react", - }, - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "apps/main-webpack/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, - "main-webpack-e2e" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [ - "main-webpack", - ], - "name": "main-webpack-e2e", - "projectType": "application", - "root": "apps/main-webpack-e2e", - "sourceRoot": "apps/main-webpack-e2e/src", - "tags": [], - "targets": { - "e2e": { - "configurations": { - "production": { - "devServerTarget": "main-webpack:serve:production", - }, - }, - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/main-webpack-e2e/cypress.config.ts", - "devServerTarget": "main-webpack:serve:development", - "testingType": "e2e", - }, - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/main-webpack-e2e/**/*.{js,ts}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - }, - }, - "my-plugin-e2e" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [ - "my-plugin", - ], - "name": "my-plugin-e2e", - "projectType": "application", - "root": "apps/my-plugin-e2e", - "sourceRoot": "apps/my-plugin-e2e/src", - "tags": [], - "targets": { - "e2e": { - "executor": "@nrwl/nx-plugin:e2e", - "options": { - "jestConfig": "apps/my-plugin-e2e/jest.config.ts", - "target": "my-plugin:build", - }, - }, - }, - }, - "react-rollup-e2e" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [ - "react-rollup", - ], - "name": "react-rollup-e2e", - "projectType": "application", - "root": "apps/react-rollup-e2e", - "sourceRoot": "apps/react-rollup-e2e/src", - "tags": [], - "targets": { - "e2e": { - "configurations": { - "ci": { - "devServerTarget": "react-rollup:storybook:ci", - }, - }, - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/react-rollup-e2e/cypress.config.ts", - "devServerTarget": "react-rollup:storybook", - "testingType": "e2e", - }, - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/react-rollup-e2e/**/*.{js,ts}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - }, - }, - "react-vite-e2e" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [ - "react-vite", - ], - "name": "react-vite-e2e", - "projectType": "application", - "root": "apps/react-vite-e2e", - "sourceRoot": "apps/react-vite-e2e/src", - "tags": [], - "targets": { - "e2e": { - "configurations": { - "ci": { - "devServerTarget": "react-vite:storybook:ci", - }, - }, - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/react-vite-e2e/cypress.config.ts", - "devServerTarget": "react-vite:storybook", - "testingType": "e2e", - }, - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "apps/react-vite-e2e/**/*.{js,ts}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - }, - }, - "my-plugin" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "my-plugin", - "projectType": "library", - "root": "libs/my-plugin", - "sourceRoot": "libs/my-plugin/src", - "tags": [], - "targets": { - "build": { - "executor": "@nrwl/js:tsc", - "options": { - "assets": [ - "libs/my-plugin/*.md", - { - "glob": "**/!(*.ts)", - "input": "./libs/my-plugin/src", - "output": "./src", - }, - { - "glob": "**/*.d.ts", - "input": "./libs/my-plugin/src", - "output": "./src", - }, - { - "glob": "generators.json", - "input": "./libs/my-plugin", - "output": ".", - }, - { - "glob": "executors.json", - "input": "./libs/my-plugin", - "output": ".", - }, - ], - "main": "libs/my-plugin/src/index.ts", - "outputPath": "dist/libs/my-plugin", - "tsConfig": "libs/my-plugin/tsconfig.lib.json", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/my-plugin/**/*.ts", - "libs/my-plugin/generators.json", - "libs/my-plugin/executors.json", - "libs/my-plugin/package.json", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "libs/my-plugin/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, - "mylib" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "mylib", - "projectType": "library", - "root": "libs/mylib", - "sourceRoot": "libs/mylib/src", - "tags": [], - "targets": { - "build": { - "executor": "@imported-libs/my-plugin:build", - }, - }, - }, - "react-rollup" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "react-rollup", - "projectType": "library", - "root": "libs/react-rollup", - "sourceRoot": "libs/react-rollup/src", - "tags": [], - "targets": { - "build": { - "executor": "@nrwl/rollup:rollup", - "options": { - "assets": [ - { - "glob": "libs/react-rollup/README.md", - "input": ".", - "output": ".", - }, - ], - "compiler": "babel", - "entryFile": "libs/react-rollup/src/index.ts", - "external": [ - "react/jsx-runtime", - ], - "outputPath": "dist/libs/react-rollup", - "project": "libs/react-rollup/package.json", - "rollupConfig": "@nrwl/react/plugins/bundle-rollup", - "tsConfig": "libs/react-rollup/tsconfig.lib.json", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "build-storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:build", - "options": { - "configDir": "libs/react-rollup/.storybook", - "outputDir": "dist/storybook/react-rollup", - "uiFramework": "@storybook/react", - }, - "outputs": [ - "{options.outputDir}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/react-rollup/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:storybook", - "options": { - "configDir": "libs/react-rollup/.storybook", - "port": 4400, - "uiFramework": "@storybook/react", - }, - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "libs/react-rollup/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, - "react-rollup-2" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "react-rollup-2", - "projectType": "library", - "root": "libs/react-rollup-2", - "sourceRoot": "libs/react-rollup-2/src", - "tags": [], - "targets": { - "build": { - "executor": "@nrwl/rollup:rollup", - "options": { - "assets": [ - { - "glob": "libs/react-rollup-2/README.md", - "input": ".", - "output": ".", - }, - ], - "compiler": "babel", - "entryFile": "libs/react-rollup-2/src/index.ts", - "external": [ - "react/jsx-runtime", - ], - "outputPath": "dist/libs/react-rollup-2", - "project": "libs/react-rollup-2/package.json", - "rollupConfig": "@nrwl/react/plugins/bundle-rollup", - "tsConfig": "libs/react-rollup-2/tsconfig.lib.json", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/react-rollup-2/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "libs/react-rollup-2/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, - "react-vite" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "react-vite", - "projectType": "library", - "root": "libs/react-vite", - "sourceRoot": "libs/react-vite/src", - "tags": [], - "targets": { - "build": { - "configurations": { - "development": { - "mode": "development", - }, - "production": { - "mode": "production", - }, - }, - "defaultConfiguration": "production", - "executor": "@nrwl/vite:build", - "options": { - "outputPath": "dist/libs/react-vite", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "build-storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:build", - "options": { - "configDir": "libs/react-vite/.storybook", - "outputDir": "dist/storybook/react-vite", - "uiFramework": "@storybook/react", - }, - "outputs": [ - "{options.outputDir}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/react-vite/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "storybook": { - "configurations": { - "ci": { - "quiet": true, - }, - }, - "executor": "@nrwl/storybook:storybook", - "options": { - "configDir": "libs/react-vite/.storybook", - "port": 4400, - "uiFramework": "@storybook/react", - }, - }, - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/libs/react-vite", - }, - "outputs": [ - "coverage/libs/react-vite", - ], - }, - }, - }, - "react-vite-2" => { - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "name": "react-vite-2", - "projectType": "library", - "root": "libs/react-vite-2", - "sourceRoot": "libs/react-vite-2/src", - "tags": [], - "targets": { - "build": { - "configurations": { - "development": { - "mode": "development", - }, - "production": { - "mode": "production", - }, - }, - "defaultConfiguration": "production", - "executor": "@nrwl/vite:build", - "options": { - "outputPath": "dist/libs/react-vite-2", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/react-vite-2/**/*.{ts,tsx,js,jsx}", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/libs/react-vite-2", - }, - "outputs": [ - "coverage/libs/react-vite-2", - ], - }, - }, - }, - "utils-one" => { - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "name": "utils-one", - "projectType": "library", - "root": "libs/utils/one", - "sourceRoot": "libs/utils/one/src", - "tags": [], - "targets": { - "build": { - "executor": "@nrwl/webpack:webpack", - "options": { - "assets": [], - "main": "libs/utils/one/src/index.ts", - "outputPath": "dist/libs/utils/one", - "tsConfig": "libs/utils/one/tsconfig.lib.json", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/utils/one/**/*.ts", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "libs/utils/one/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, - "utils-three-vite" => { - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "name": "utils-three-vite", - "projectType": "library", - "root": "libs/utils/three-vite", - "sourceRoot": "libs/utils/three-vite/src", - "tags": [], - "targets": { - "build": { - "executor": "@nrwl/vite:build", - "options": { - "outputPath": "dist/libs/utils/three-vite", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/utils/three-vite/**/*.ts", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "libs/utils/three-vite/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, - "utils-two" => { - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "name": "utils-two", - "projectType": "library", - "root": "libs/utils/two", - "sourceRoot": "libs/utils/two/src", - "tags": [], - "targets": { - "build": { - "executor": "@nrwl/webpack:webpack", - "options": { - "assets": [], - "main": "libs/utils/two/src/index.ts", - "outputPath": "dist/libs/utils/two", - "tsConfig": "libs/utils/two/tsconfig.lib.json", - }, - "outputs": [ - "{options.outputPath}", - ], - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "options": { - "lintFilePatterns": [ - "libs/utils/two/**/*.ts", - ], - }, - "outputs": [ - "{options.outputFile}", - ], - }, - "test": { - "executor": "@nrwl/jest:jest", - "options": { - "jestConfig": "libs/utils/two/jest.config.ts", - "passWithNoTests": true, - }, - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}", - ], - }, - }, - }, -} -`; diff --git a/packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.spec.ts b/packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.spec.ts deleted file mode 100644 index 92c1c75fe21fd..0000000000000 --- a/packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - addProjectConfiguration, - getProjects, - ProjectConfiguration, - Tree, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import refactorExecutorOptions from './refactor-executor-options'; -import * as variousProjects from './test-configs/various-projects.json'; - -describe('update the executor options to match the new schema', () => { - let tree: Tree; - - describe('for non-angular projects', () => { - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - for (const [name, project] of Object.entries(variousProjects)) { - addProjectConfiguration(tree, name, project as ProjectConfiguration); - } - }); - - it(`should update the target options`, async () => { - await refactorExecutorOptions(tree); - - const projects = getProjects(tree); - expect(projects).toMatchSnapshot(); - }); - }); -}); diff --git a/packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.ts b/packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.ts deleted file mode 100644 index 3df99cb64a507..0000000000000 --- a/packages/storybook/src/migrations/update-15-4-6/refactor-executor-options.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - formatFiles, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; - -export default async function (tree: Tree) { - updateNonAngularStorybookBuildTargets(tree); - updateNonAngularStorybookServeTargets(tree); - await formatFiles(tree); -} - -function updateNonAngularStorybookBuildTargets(tree: Tree) { - forEachExecutorOptions( - tree, - '@nrwl/storybook:build', - (_options, projectName, targetName, configuration) => { - if (!configuration) { - return; - } - const projectConfiguration = readProjectConfiguration(tree, projectName); - - if (!projectConfiguration.targets[targetName].options) { - projectConfiguration.targets[targetName].options = {}; - } - - if (!projectConfiguration.targets[targetName].options.configDir) { - projectConfiguration.targets[targetName].options.configDir = - projectConfiguration.targets[targetName].options.config?.configFolder; - } - - if (!projectConfiguration.targets[targetName].options.outputDir) { - projectConfiguration.targets[targetName].options.outputDir = - projectConfiguration.targets[targetName].options.outputPath; - } - - if (!projectConfiguration.targets[targetName].options.docs) { - projectConfiguration.targets[targetName].options.docs = - projectConfiguration.targets[targetName].options.docsMode; - } - - projectConfiguration.targets[targetName].outputs = - projectConfiguration.targets[targetName].outputs?.map( - (output: string) => - output.replace('{options.outputPath}', '{options.outputDir}') - ); - - delete projectConfiguration.targets[targetName].options.config; - delete projectConfiguration.targets[targetName].options.outputPath; - delete projectConfiguration.targets[targetName].options.docsMode; - - updateProjectConfiguration(tree, projectName, { - ...projectConfiguration, - }); - } - ); -} - -function updateNonAngularStorybookServeTargets(tree: Tree) { - forEachExecutorOptions( - tree, - '@nrwl/storybook:storybook', - (_options, projectName, targetName, configuration) => { - if (!configuration) { - return; - } - - const projectConfiguration = readProjectConfiguration(tree, projectName); - - if (!projectConfiguration.targets[targetName].options) { - projectConfiguration.targets[targetName].options = {}; - } - - if (!projectConfiguration.targets[targetName].options.configDir) { - projectConfiguration.targets[targetName].options.configDir = - projectConfiguration.targets[targetName].options.config?.configFolder; - } - - if (!projectConfiguration.targets[targetName].options.docs) { - projectConfiguration.targets[targetName].options.docs = - projectConfiguration.targets[targetName].options.docsMode; - } - - delete projectConfiguration.targets[targetName].options.config; - delete projectConfiguration.targets[targetName].options.docsMode; - - updateProjectConfiguration(tree, projectName, { - ...projectConfiguration, - }); - } - ); -} diff --git a/packages/storybook/src/migrations/update-15-4-6/test-configs/various-projects.json b/packages/storybook/src/migrations/update-15-4-6/test-configs/various-projects.json deleted file mode 100644 index 975e457145990..0000000000000 --- a/packages/storybook/src/migrations/update-15-4-6/test-configs/various-projects.json +++ /dev/null @@ -1,828 +0,0 @@ -{ - "main-vite-new": { - "name": "main-vite-new", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-vite-new/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nrwl/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { "outputPath": "dist/apps/main-vite-new" }, - "configurations": { - "development": { "mode": "development" }, - "production": { "mode": "production" } - } - }, - "serve": { - "executor": "@nrwl/vite:dev-server", - "defaultConfiguration": "development", - "options": { "buildTarget": "main-vite-new:build" }, - "configurations": { - "development": { - "buildTarget": "main-vite-new:build:development", - "hmr": true - }, - "production": { - "buildTarget": "main-vite-new:build:production", - "hmr": false - } - } - }, - "test": { - "executor": "@nrwl/vite:test", - "outputs": ["coverage/apps/main-vite-new"], - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/apps/main-vite-new" - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/main-vite-new/**/*.{ts,tsx,js,jsx}"] - } - }, - "storybook": { - "executor": "@nrwl/storybook:storybook", - "options": { - "uiFramework": "@storybook/react", - "port": 4400, - "configDir": "apps/main-vite-new/.storybook" - }, - "configurations": { "ci": { "quiet": true } } - }, - "build-storybook": { - "executor": "@nrwl/storybook:build", - "outputs": ["{options.outputDir}"], - "options": { - "uiFramework": "@storybook/react", - "outputDir": "dist/storybook/main-vite-new", - "configDir": "apps/main-vite-new/.storybook" - }, - "configurations": { "ci": { "quiet": true } } - } - }, - "tags": [], - "root": "apps/main-vite-new" - }, - "main-vite": { - "name": "main-vite", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-vite/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nrwl/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { "outputPath": "dist/apps/main-vite" }, - "configurations": { - "development": { "mode": "development" }, - "production": { "mode": "production" } - } - }, - "serve": { - "executor": "@nrwl/vite:dev-server", - "defaultConfiguration": "development", - "options": { "buildTarget": "main-vite:build" }, - "configurations": { - "development": { - "buildTarget": "main-vite:build:development", - "hmr": true - }, - "production": { - "buildTarget": "main-vite:build:production", - "hmr": false - } - } - }, - "test": { - "executor": "@nrwl/vite:test", - "outputs": ["coverage/apps/main-vite"], - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/apps/main-vite" - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/main-vite/**/*.{ts,tsx,js,jsx}"] - } - }, - "storybook": { - "executor": "@nrwl/storybook:storybook", - "options": { - "uiFramework": "@storybook/react", - "port": 4400, - "config": { "configFolder": "apps/main-vite/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - }, - "build-storybook": { - "executor": "@nrwl/storybook:build", - "outputs": ["{options.outputPath}"], - "options": { - "uiFramework": "@storybook/react", - "outputPath": "dist/storybook/main-vite", - "config": { "configFolder": "apps/main-vite/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - } - }, - "tags": [], - "root": "apps/main-vite" - }, - "main-vite-e2e": { - "name": "main-vite-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-vite-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/main-vite-e2e/cypress.config.ts", - "devServerTarget": "main-vite:serve:development", - "testingType": "e2e" - }, - "configurations": { - "production": { "devServerTarget": "main-vite:serve:production" } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { "lintFilePatterns": ["apps/main-vite-e2e/**/*.{js,ts}"] } - } - }, - "tags": [], - "implicitDependencies": ["main-vite"], - "root": "apps/main-vite-e2e" - }, - "main-vite-ts": { - "name": "main-vite-ts", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-vite-ts/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nrwl/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { "outputPath": "dist/apps/main-vite-ts" }, - "configurations": { - "development": { "mode": "development" }, - "production": { "mode": "production" } - } - }, - "serve": { - "executor": "@nrwl/vite:dev-server", - "defaultConfiguration": "development", - "options": { "buildTarget": "main-vite-ts:build" }, - "configurations": { - "development": { - "buildTarget": "main-vite-ts:build:development", - "hmr": true - }, - "production": { - "buildTarget": "main-vite-ts:build:production", - "hmr": false - } - } - }, - "test": { - "executor": "@nrwl/vite:test", - "outputs": ["coverage/apps/main-vite-ts"], - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/apps/main-vite-ts" - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/main-vite-ts/**/*.{ts,tsx,js,jsx}"] - } - }, - "storybook": { - "executor": "@nrwl/storybook:storybook", - "options": { - "uiFramework": "@storybook/react", - "port": 4400, - "config": { "configFolder": "apps/main-vite-ts/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - }, - "build-storybook": { - "executor": "@nrwl/storybook:build", - "outputs": ["{options.outputPath}"], - "options": { - "uiFramework": "@storybook/react", - "outputPath": "dist/storybook/main-vite-ts", - "config": { "configFolder": "apps/main-vite-ts/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - } - }, - "tags": [], - "root": "apps/main-vite-ts" - }, - "main-vite-ts-e2e": { - "name": "main-vite-ts-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-vite-ts-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/main-vite-ts-e2e/cypress.config.ts", - "devServerTarget": "main-vite-ts:serve:development", - "testingType": "e2e" - }, - "configurations": { - "production": { "devServerTarget": "main-vite-ts:serve:production" } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/main-vite-ts-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["main-vite-ts"], - "root": "apps/main-vite-ts-e2e" - }, - "main-webpack": { - "name": "main-webpack", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-webpack/src", - "projectType": "application", - "targets": { - "build": { - "executor": "@nrwl/webpack:webpack", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { - "compiler": "babel", - "outputPath": "dist/apps/main-webpack", - "index": "apps/main-webpack/src/index.html", - "baseHref": "/", - "main": "apps/main-webpack/src/main.tsx", - "polyfills": "apps/main-webpack/src/polyfills.ts", - "tsConfig": "apps/main-webpack/tsconfig.app.json", - "assets": [ - "apps/main-webpack/src/favicon.ico", - "apps/main-webpack/src/assets" - ], - "styles": ["apps/main-webpack/src/styles.css"], - "scripts": [], - "webpackConfig": "@nrwl/react/plugins/webpack" - }, - "configurations": { - "development": { - "extractLicenses": false, - "optimization": false, - "sourceMap": true, - "vendorChunk": true - }, - "production": { - "fileReplacements": [ - { - "replace": "apps/main-webpack/src/environments/environment.ts", - "with": "apps/main-webpack/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false - } - } - }, - "serve": { - "executor": "@nrwl/webpack:dev-server", - "defaultConfiguration": "development", - "options": { "buildTarget": "main-webpack:build", "hmr": true }, - "configurations": { - "development": { "buildTarget": "main-webpack:build:development" }, - "production": { - "buildTarget": "main-webpack:build:production", - "hmr": false - } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/main-webpack/**/*.{ts,tsx,js,jsx}"] - } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/main-webpack/jest.config.ts", - "passWithNoTests": true - } - }, - "storybook": { - "executor": "@nrwl/storybook:storybook", - "options": { - "uiFramework": "@storybook/react", - "port": 4400, - "config": { "configFolder": "apps/main-webpack/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - }, - "build-storybook": { - "executor": "@nrwl/storybook:build", - "outputs": ["{options.outputPath}"], - "options": { - "uiFramework": "@storybook/react", - "outputPath": "dist/storybook/main-webpack", - "config": { "configFolder": "apps/main-webpack/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - } - }, - "tags": [], - "root": "apps/main-webpack" - }, - "main-webpack-e2e": { - "name": "main-webpack-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/main-webpack-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/main-webpack-e2e/cypress.config.ts", - "devServerTarget": "main-webpack:serve:development", - "testingType": "e2e" - }, - "configurations": { - "production": { "devServerTarget": "main-webpack:serve:production" } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/main-webpack-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["main-webpack"], - "root": "apps/main-webpack-e2e" - }, - "my-plugin-e2e": { - "name": "my-plugin-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/my-plugin-e2e/src", - "targets": { - "e2e": { - "executor": "@nrwl/nx-plugin:e2e", - "options": { - "target": "my-plugin:build", - "jestConfig": "apps/my-plugin-e2e/jest.config.ts" - } - } - }, - "tags": [], - "implicitDependencies": ["my-plugin"], - "root": "apps/my-plugin-e2e" - }, - "react-rollup-e2e": { - "name": "react-rollup-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/react-rollup-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/react-rollup-e2e/cypress.config.ts", - "devServerTarget": "react-rollup:storybook", - "testingType": "e2e" - }, - "configurations": { - "ci": { "devServerTarget": "react-rollup:storybook:ci" } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/react-rollup-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["react-rollup"], - "root": "apps/react-rollup-e2e" - }, - "react-vite-e2e": { - "name": "react-vite-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/react-vite-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/react-vite-e2e/cypress.config.ts", - "devServerTarget": "react-vite:storybook", - "testingType": "e2e" - }, - "configurations": { - "ci": { "devServerTarget": "react-vite:storybook:ci" } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { "lintFilePatterns": ["apps/react-vite-e2e/**/*.{js,ts}"] } - } - }, - "tags": [], - "implicitDependencies": ["react-vite"], - "root": "apps/react-vite-e2e" - }, - "my-plugin": { - "name": "my-plugin", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/my-plugin/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nrwl/js:tsc", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/my-plugin", - "main": "libs/my-plugin/src/index.ts", - "tsConfig": "libs/my-plugin/tsconfig.lib.json", - "assets": [ - "libs/my-plugin/*.md", - { - "input": "./libs/my-plugin/src", - "glob": "**/!(*.ts)", - "output": "./src" - }, - { - "input": "./libs/my-plugin/src", - "glob": "**/*.d.ts", - "output": "./src" - }, - { - "input": "./libs/my-plugin", - "glob": "generators.json", - "output": "." - }, - { - "input": "./libs/my-plugin", - "glob": "executors.json", - "output": "." - } - ] - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": [ - "libs/my-plugin/**/*.ts", - "libs/my-plugin/generators.json", - "libs/my-plugin/executors.json", - "libs/my-plugin/package.json" - ] - } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/my-plugin/jest.config.ts", - "passWithNoTests": true - } - } - }, - "tags": [], - "root": "libs/my-plugin" - }, - "mylib": { - "name": "mylib", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "library", - "sourceRoot": "libs/mylib/src", - "targets": { "build": { "executor": "@imported-libs/my-plugin:build" } }, - "tags": [], - "root": "libs/mylib" - }, - "react-rollup": { - "name": "react-rollup", - "sourceRoot": "libs/react-rollup/src", - "projectType": "library", - "tags": [], - "targets": { - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/react-rollup/**/*.{ts,tsx,js,jsx}"] - } - }, - "build": { - "executor": "@nrwl/rollup:rollup", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/react-rollup", - "tsConfig": "libs/react-rollup/tsconfig.lib.json", - "project": "libs/react-rollup/package.json", - "entryFile": "libs/react-rollup/src/index.ts", - "external": ["react/jsx-runtime"], - "rollupConfig": "@nrwl/react/plugins/bundle-rollup", - "compiler": "babel", - "assets": [ - { - "glob": "libs/react-rollup/README.md", - "input": ".", - "output": "." - } - ] - } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/react-rollup/jest.config.ts", - "passWithNoTests": true - } - }, - "storybook": { - "executor": "@nrwl/storybook:storybook", - "options": { - "uiFramework": "@storybook/react", - "port": 4400, - "config": { "configFolder": "libs/react-rollup/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - }, - "build-storybook": { - "executor": "@nrwl/storybook:build", - "outputs": ["{options.outputPath}"], - "options": { - "uiFramework": "@storybook/react", - "outputPath": "dist/storybook/react-rollup", - "config": { "configFolder": "libs/react-rollup/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - } - }, - "root": "libs/react-rollup" - }, - "react-rollup-2": { - "name": "react-rollup-2", - "sourceRoot": "libs/react-rollup-2/src", - "projectType": "library", - "tags": [], - "targets": { - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/react-rollup-2/**/*.{ts,tsx,js,jsx}"] - } - }, - "build": { - "executor": "@nrwl/rollup:rollup", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/react-rollup-2", - "tsConfig": "libs/react-rollup-2/tsconfig.lib.json", - "project": "libs/react-rollup-2/package.json", - "entryFile": "libs/react-rollup-2/src/index.ts", - "external": ["react/jsx-runtime"], - "rollupConfig": "@nrwl/react/plugins/bundle-rollup", - "compiler": "babel", - "assets": [ - { - "glob": "libs/react-rollup-2/README.md", - "input": ".", - "output": "." - } - ] - } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/react-rollup-2/jest.config.ts", - "passWithNoTests": true - } - } - }, - "root": "libs/react-rollup-2" - }, - "react-vite": { - "name": "react-vite", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/react-vite/src", - "projectType": "library", - "tags": [], - "targets": { - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/react-vite/**/*.{ts,tsx,js,jsx}"] - } - }, - "build": { - "executor": "@nrwl/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { "outputPath": "dist/libs/react-vite" }, - "configurations": { - "development": { "mode": "development" }, - "production": { "mode": "production" } - } - }, - "test": { - "executor": "@nrwl/vite:test", - "outputs": ["coverage/libs/react-vite"], - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/libs/react-vite" - } - }, - "storybook": { - "executor": "@nrwl/storybook:storybook", - "options": { - "uiFramework": "@storybook/react", - "port": 4400, - "config": { "configFolder": "libs/react-vite/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - }, - "build-storybook": { - "executor": "@nrwl/storybook:build", - "outputs": ["{options.outputPath}"], - "options": { - "uiFramework": "@storybook/react", - "outputPath": "dist/storybook/react-vite", - "config": { "configFolder": "libs/react-vite/.storybook" } - }, - "configurations": { "ci": { "quiet": true } } - } - }, - "root": "libs/react-vite" - }, - "react-vite-2": { - "name": "react-vite-2", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/react-vite-2/src", - "projectType": "library", - "tags": [], - "targets": { - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/react-vite-2/**/*.{ts,tsx,js,jsx}"] - } - }, - "build": { - "executor": "@nrwl/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { "outputPath": "dist/libs/react-vite-2" }, - "configurations": { - "development": { "mode": "development" }, - "production": { "mode": "production" } - } - }, - "test": { - "executor": "@nrwl/vite:test", - "outputs": ["coverage/libs/react-vite-2"], - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverage/libs/react-vite-2" - } - } - }, - "root": "libs/react-vite-2" - }, - "utils-one": { - "name": "utils-one", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/utils/one/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nrwl/webpack:webpack", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/utils/one", - "main": "libs/utils/one/src/index.ts", - "tsConfig": "libs/utils/one/tsconfig.lib.json", - "assets": [] - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { "lintFilePatterns": ["libs/utils/one/**/*.ts"] } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/utils/one/jest.config.ts", - "passWithNoTests": true - } - } - }, - "tags": [], - "root": "libs/utils/one" - }, - "utils-three-vite": { - "name": "utils-three-vite", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/utils/three-vite/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nrwl/vite:build", - "outputs": ["{options.outputPath}"], - "options": { "outputPath": "dist/libs/utils/three-vite" } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { "lintFilePatterns": ["libs/utils/three-vite/**/*.ts"] } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/utils/three-vite/jest.config.ts", - "passWithNoTests": true - } - } - }, - "tags": [], - "root": "libs/utils/three-vite" - }, - "utils-two": { - "name": "utils-two", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/utils/two/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nrwl/webpack:webpack", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/utils/two", - "main": "libs/utils/two/src/index.ts", - "tsConfig": "libs/utils/two/tsconfig.lib.json", - "assets": [] - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { "lintFilePatterns": ["libs/utils/two/**/*.ts"] } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "libs/utils/two/jest.config.ts", - "passWithNoTests": true - } - } - }, - "tags": [], - "root": "libs/utils/two" - } -} diff --git a/packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.spec.ts b/packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.spec.ts deleted file mode 100644 index 16679c3c8e1f6..0000000000000 --- a/packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { readJson, writeJson, addProjectConfiguration, Tree } from '@nx/devkit'; -import update from './ensure-webpack-package'; - -describe('ensure-webpack-package', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace(); - writeJson(tree, 'package.json', { - dependencies: {}, - devDependencies: { - '@nrwl/react': '15.5.0', - }, - }); - }); - - it.each` - config - ${'main.ts'} - ${'main.js'} - `( - 'should install @nrwl/webpack if it is needed by React project', - async ({ config }) => { - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - }); - tree.write( - `myapp/.storybook/${config}`, - ` - module.exports = { - addons: ['@nrwl/react/plugins/storybook'] - }; - ` - ); - - await update(tree); - - const packageJson = readJson(tree, 'package.json'); - expect(packageJson.devDependencies).toEqual({ - '@nrwl/react': expect.any(String), - '@nrwl/webpack': expect.any(String), - }); - } - ); - - it.each` - config - ${'main.ts'} - ${'main.js'} - ${null} - `( - 'should not install @nrwl/webpack if it is not needed by React project', - async ({ config }) => { - addProjectConfiguration(tree, 'myapp', { - root: 'myapp', - }); - - if (config) { - tree.write( - `myapp/.storybook/${config}`, - ` - module.exports = { - addons: [] - }; - ` - ); - } - - await update(tree); - - const packageJson = readJson(tree, 'package.json'); - expect(packageJson.devDependencies).toEqual({ - '@nrwl/react': expect.any(String), - }); - } - ); -}); diff --git a/packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.ts b/packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.ts deleted file mode 100644 index d74c012dd18a0..0000000000000 --- a/packages/storybook/src/migrations/update-15-5-3/ensure-webpack-package.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - addDependenciesToPackageJson, - getProjects, - joinPathFragments, - Tree, -} from '@nx/devkit'; -import { nxVersion } from '../../utils/versions'; - -// Add @nx/webpack as needed. -// See: https://github.com/nrwl/nx/issues/14455 -export default async function update(tree: Tree) { - const projects = getProjects(tree); - const reactPlugin = '@nrwl/react/plugins/storybook'; - let shouldInstall = false; - - for (const [, config] of projects) { - let sbConfigPath = joinPathFragments(config.root, '.storybook/main.ts'); - - if (!tree.exists(sbConfigPath)) { - sbConfigPath = joinPathFragments(config.root, '.storybook/main.js'); - } - - if (!tree.exists(sbConfigPath)) { - continue; - } - - const sbConfig = tree.read(sbConfigPath, 'utf-8'); - if (sbConfig.includes(reactPlugin)) { - shouldInstall = true; - break; - } - } - - if (shouldInstall) { - return addDependenciesToPackageJson( - tree, - {}, - { '@nrwl/webpack': nxVersion } - ); - } -} diff --git a/packages/storybook/src/migrations/update-15-7-0/__snapshots__/add-addon-essentials-to-all.spec.ts.snap b/packages/storybook/src/migrations/update-15-7-0/__snapshots__/add-addon-essentials-to-all.spec.ts.snap deleted file mode 100644 index e55f8a5c383ca..0000000000000 --- a/packages/storybook/src/migrations/update-15-7-0/__snapshots__/add-addon-essentials-to-all.spec.ts.snap +++ /dev/null @@ -1,374 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 1`] = ` -"const rootMain = require('../../../.storybook/main'); -const { mergeConfig } = require('vite'); -const viteTsConfigPaths = require('vite-tsconfig-paths').default; - -module.exports = { - ...rootMain, - core: { ...rootMain.core, builder: 'webpack5' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: ['@storybook/addon-essentials'], - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 2`] = ` -"import { rootMain } from '../../../.storybook/main'; -import type { StorybookConfig } from '@storybook/core-common'; -import { mergeConfig } from 'vite'; -import viteTsConfigPaths from 'vite-tsconfig-paths'; - -const config: StorybookConfig = { - ...rootMain, - core: { ...rootMain.core, builder: '@storybook/builder-vite' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: ['@storybook/addon-essentials', ...(rootMain.addons || [])], - async viteFinal(config: any) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; - -module.exports = config; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 3`] = ` -"const rootMain = require('../../../.storybook/main'); -const { mergeConfig } = require('vite'); -const viteTsConfigPaths = require('vite-tsconfig-paths').default; - -module.exports = { - ...rootMain, - core: { ...rootMain.core, builder: 'webpack5' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: [ - '@storybook/addon-essentials', - ...rootMain.addons, - '@nrwl/react/plugins/storybook', - ], - webpackFinal: async (config, { configType }) => { - // apply any global webpack configs that might have been specified in .storybook/main.js - if (rootMain.webpackFinal) { - config = await rootMain.webpackFinal(config, { configType }); - } - - // add your own webpack tweaks if needed - - return config; - }, - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 4`] = ` -"// project: react-rollup -const rootMain = require('../../../.storybook/main'); -// Use the following syntax to add addons! -rootMain.addons.push('@storybook/addon-essentials', '@storybook/addon-a11y'); -rootMain.stories.push( - ...['../src/lib/**/*.stories.mdx', '../src/lib/**/*.stories.@(js|jsx|ts|tsx)'] -); - -module.exports = rootMain; - -module.exports.core = { ...module.exports.core, builder: 'webpack5' }; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 5`] = ` -"// project: react-rollup-3 -const rootMain = require('../../../.storybook/main'); -// Use the following syntax to add addons! -rootMain.addons.push('@storybook/addon-essentials'); -rootMain.stories.push( - ...['../src/lib/**/*.stories.mdx', '../src/lib/**/*.stories.@(js|jsx|ts|tsx)'] -); - -module.exports = rootMain; - -module.exports.core = { ...module.exports.core, builder: 'webpack5' }; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 6`] = ` -"// project: react-rollup-4 -const rootMain = require('../../../.storybook/main'); -rootMain.addons.push('@storybook/addon-essentials'); -rootMain.stories.push( - ...['../src/lib/**/*.stories.mdx', '../src/lib/**/*.stories.@(js|jsx|ts|tsx)'] -); - -module.exports = rootMain; - -module.exports.core = { ...module.exports.core, builder: 'webpack5' }; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 7`] = ` -"const rootMain = require('../../../.storybook/main'); -const { mergeConfig } = require('vite'); -const viteTsConfigPaths = require('vite-tsconfig-paths').default; - -module.exports = { - ...rootMain, - core: { ...rootMain.core, builder: 'webpack5' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: [ - '@storybook/addon-essentials', - ...rootMain.addons, - '@nrwl/react/plugins/storybook', - ], - webpackFinal: async (config, { configType }) => { - // apply any global webpack configs that might have been specified in .storybook/main.js - if (rootMain.webpackFinal) { - config = await rootMain.webpackFinal(config, { configType }); - } - - // add your own webpack tweaks if needed - - return config; - }, - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should add addon-essentials to main.js|ts where possible 8`] = ` -" - some invalid stuff - " -`; - -exports[`Add addon-essentials to project-level main.js files should remove addon-essentials from root config file 1`] = ` -"module.exports = { - addons: ['@storybook/addon-knobs'], -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove addon-essentials from root config typescript file 1`] = ` -"import type { StorybookConfig } from '@storybook/core-common'; - -export const rootMain: StorybookConfig = { - addons: ['@storybook/addon-knobs'], -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 1`] = ` -"const { mergeConfig } = require('vite'); -const viteTsConfigPaths = require('vite-tsconfig-paths').default; - -module.exports = { - core: { builder: 'webpack5' }, - stories: [ - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: ['@storybook/addon-essentials'], - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 2`] = ` -"import type { StorybookConfig } from '@storybook/core-common'; -import { mergeConfig } from 'vite'; -import viteTsConfigPaths from 'vite-tsconfig-paths'; - -const config: StorybookConfig = { - core: { builder: '@storybook/builder-vite' }, - stories: [ - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: ['@storybook/addon-essentials'], - async viteFinal(config: any) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; - -module.exports = config; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 3`] = ` -"const { mergeConfig } = require('vite'); -const viteTsConfigPaths = require('vite-tsconfig-paths').default; - -module.exports = { - core: { builder: 'webpack5' }, - stories: [ - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: ['@storybook/addon-essentials', '@nrwl/react/plugins/storybook'], - webpackFinal: async (config, { configType }) => { - // apply any global webpack configs that might have been specified in .storybook/main.js - - // add your own webpack tweaks if needed - - return config; - }, - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 4`] = ` -"// project: react-rollup - -// Use the following syntax to add addons! - -module.exports = rootMain; - -module.exports.core = { ...module.exports.core, builder: 'webpack5' }; -module.exports.addons = [ - '@storybook/addon-essentials', - '@storybook/addon-a11y', -]; -module.exports.stories = [ - '../src/lib/**/*.stories.mdx', - '../src/lib/**/*.stories.@(js|jsx|ts|tsx)', -]; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 5`] = ` -"// project: react-rollup-3 - -// Use the following syntax to add addons! - -module.exports = rootMain; - -module.exports.core = { ...module.exports.core, builder: 'webpack5' }; -module.exports.addons = ['@storybook/addon-essentials']; -module.exports.stories = [ - '../src/lib/**/*.stories.mdx', - '../src/lib/**/*.stories.@(js|jsx|ts|tsx)', -]; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 6`] = ` -"// project: react-rollup-4 - -module.exports = rootMain; - -module.exports.core = { ...module.exports.core, builder: 'webpack5' }; -module.exports.addons = ['@storybook/addon-essentials']; -module.exports.stories = [ - '../src/lib/**/*.stories.mdx', - '../src/lib/**/*.stories.@(js|jsx|ts|tsx)', -]; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 7`] = ` -"const { mergeConfig } = require('vite'); -const viteTsConfigPaths = require('vite-tsconfig-paths').default; - -module.exports = { - core: { builder: 'webpack5' }, - stories: [ - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: ['@storybook/addon-essentials', '@nrwl/react/plugins/storybook'], - webpackFinal: async (config, { configType }) => { - // apply any global webpack configs that might have been specified in .storybook/main.js - - // add your own webpack tweaks if needed - - return config; - }, - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, -}; -" -`; - -exports[`Add addon-essentials to project-level main.js files should remove the root config import and delete root file 8`] = ` -" - some invalid stuff - " -`; diff --git a/packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.spec.ts b/packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.spec.ts deleted file mode 100644 index 130b5d5740280..0000000000000 --- a/packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.spec.ts +++ /dev/null @@ -1,300 +0,0 @@ -import 'nx/src/internal-testing-utils/mock-project-graph'; - -import { - addProjectConfiguration, - ProjectConfiguration, - Tree, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import * as variousProjects from './test-configs/various-configs.json'; -import addAddonEssentialsToAll from './add-addon-essentials-to-all'; - -describe('Add addon-essentials to project-level main.js files', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - addAllProjectsToWorkspace(tree); - }); - - it(`should add addon-essentials to main.js|ts where possible`, async () => { - tree.write( - '.storybook/main.js', - `module.exports = { - stories: [], - addons: ['@storybook/addon-essentials', '@storybook/addon-knobs'], - }; - ` - ); - await addAddonEssentialsToAll(tree); - expect( - tree.read('apps/main-vite/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/main-vite-ts/.storybook/main.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/main-webpack/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-rollup/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-rollup-3/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-rollup-4/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-vite/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-vite-2/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - }); - - it('should remove addon-essentials from root config file', async () => { - tree.write( - '.storybook/main.js', - `module.exports = { - stories: [], - addons: ['@storybook/addon-essentials', '@storybook/addon-knobs'], - }; - ` - ); - await addAddonEssentialsToAll(tree); - expect(tree.read('.storybook/main.js', 'utf-8')).toMatchSnapshot(); - }); - - it('should remove addon-essentials from root config typescript file', async () => { - tree.write( - '.storybook/main.ts', - ` - import type { StorybookConfig } from '@storybook/core-common'; - - export const rootMain: StorybookConfig = { - addons: ['@storybook/addon-knobs', '@storybook/addon-essentials'], - }; - ` - ); - await addAddonEssentialsToAll(tree); - expect(tree.read('.storybook/main.ts', 'utf-8')).toMatchSnapshot(); - }); - - it('should delete the root config file if it only has addon-essentials', async () => { - tree.write( - '.storybook/main.js', - `module.exports = { - stories: [], - addons: ['@storybook/addon-essentials'], - }; - ` - ); - await addAddonEssentialsToAll(tree); - expect(tree.exists('.storybook/main.js')).toBeFalsy(); - }); - - it(`should remove the root config import and delete root file`, async () => { - tree.write( - '.storybook/main.js', - `module.exports = { - stories: [], - addons: ['@storybook/addon-essentials'], - }; - ` - ); - - await addAddonEssentialsToAll(tree); - expect( - tree.read('apps/main-vite/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/main-vite-ts/.storybook/main.ts', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/main-webpack/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-rollup/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-rollup-3/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-rollup-4/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-vite/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('libs/react-vite-2/.storybook/main.js', 'utf-8') - ).toMatchSnapshot(); - - expect(tree.exists('.storybook/main.js')).toBeFalsy(); - }); -}); - -export function addAllProjectsToWorkspace(tree: Tree) { - for (const [name, project] of Object.entries(variousProjects)) { - addProjectConfiguration(tree, name, project as ProjectConfiguration); - if (project.targets['build-storybook']?.options?.configDir) { - if (name === 'main-vite-ts') { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.ts`, - ` - import { rootMain } from '../../../.storybook/main'; - import type { StorybookConfig } from '@storybook/core-common'; - import { mergeConfig } from 'vite'; - import viteTsConfigPaths from 'vite-tsconfig-paths'; - - const config: StorybookConfig = { - ...rootMain, - core: { ...rootMain.core, builder: '@storybook/builder-vite' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: [...(rootMain.addons || [])], - async viteFinal(config: any) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, - }; - - module.exports = config; - ` - ); - } else if (name === 'main-vite') { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.js`, - ` - const rootMain = require('../../../.storybook/main'); - const { mergeConfig } = require('vite'); - const viteTsConfigPaths = require('vite-tsconfig-paths').default; - - module.exports = { - ...rootMain, - core: { ...rootMain.core, builder: 'webpack5' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, - }; - ` - ); - } else if (name === 'react-vite-2') { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.js`, - ` - some invalid stuff - ` - ); - } else if (name === 'react-rollup') { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.js`, - ` - // project: ${name} - const rootMain = require('../../../.storybook/main'); - // Use the following syntax to add addons! - rootMain.addons.push('@storybook/addon-a11y'); - rootMain.stories.push( - ...['../src/lib/**/*.stories.mdx', '../src/lib/**/*.stories.@(js|jsx|ts|tsx)'] - ); - - module.exports = rootMain; - - module.exports.core = { ...module.exports.core, builder: 'webpack5' }; - ` - ); - } else if (name === 'react-rollup-3') { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.js`, - ` - // project: ${name} - const rootMain = require('../../../.storybook/main'); - // Use the following syntax to add addons! - rootMain.addons.push(); - rootMain.stories.push( - ...['../src/lib/**/*.stories.mdx', '../src/lib/**/*.stories.@(js|jsx|ts|tsx)'] - ); - - module.exports = rootMain; - - module.exports.core = { ...module.exports.core, builder: 'webpack5' }; - ` - ); - } else if (name === 'react-rollup-4') { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.js`, - ` - // project: ${name} - const rootMain = require('../../../.storybook/main'); - - rootMain.stories.push( - ...['../src/lib/**/*.stories.mdx', '../src/lib/**/*.stories.@(js|jsx|ts|tsx)'] - ); - - module.exports = rootMain; - - module.exports.core = { ...module.exports.core, builder: 'webpack5' }; - ` - ); - } else { - tree.write( - `${project.targets['build-storybook']?.options?.configDir}/main.js`, - ` - const rootMain = require('../../../.storybook/main'); - const { mergeConfig } = require('vite'); - const viteTsConfigPaths = require('vite-tsconfig-paths').default; - - module.exports = { - ...rootMain, - core: { ...rootMain.core, builder: 'webpack5' }, - stories: [ - ...rootMain.stories, - '../src/app/**/*.stories.mdx', - '../src/app/**/*.stories.@(js|jsx|ts|tsx)', - ], - addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'], - webpackFinal: async (config, { configType }) => { - // apply any global webpack configs that might have been specified in .storybook/main.js - if (rootMain.webpackFinal) { - config = await rootMain.webpackFinal(config, { configType }); - } - - // add your own webpack tweaks if needed - - return config; - }, - async viteFinal(config, { configType }) { - return mergeConfig(config, { - plugins: [ - viteTsConfigPaths({ - root: '../../../', - }), - ], - }); - }, - }; - ` - ); - } - } - } -} diff --git a/packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.ts b/packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.ts deleted file mode 100644 index ef3c55dfc2c13..0000000000000 --- a/packages/storybook/src/migrations/update-15-7-0/add-addon-essentials-to-all.ts +++ /dev/null @@ -1,374 +0,0 @@ -import { - applyChangesToString, - ChangeType, - formatFiles, - logger, - Tree, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { removeRootConfig } from './remove-root-config'; -import ts = require('typescript'); - -/** - * The purpose of this migrator is to help users move away - * from the root .storybook/ configuration folder and files. - * - * Since we cannot be sure of how users make use of the root Storybook - * directory, what we are going to do is the following: - * - * 1. Make sure that all project-level .storybook/main.js files contain - * the @storybook/addon-essentials addon. - * 2. If the root .storybook/main.js file contains the @storybook/addon-essentials remove it - * from the root - * 3. If there are things beyond the addons array in the root .storybook/main.js file, - * then keep it as it is - inform user that they need to manually need to copy over any extra stuff - * 4. If the root .storybook/main.js file is now empty, inform user that they can delete it safely - * - * Point the user to a guide that explains how to all these things. - */ - -export default async function (tree: Tree) { - const projectsThatFailedTOAddAddonEssentials = - addAddonEssentialsToAllStorybooks(tree); - - if (projectsThatFailedTOAddAddonEssentials.length) { - logger.info( - ` - We could not add the @storybook/addon-essentials addon - to the following projects' Storybook configurations: - - ${projectsThatFailedTOAddAddonEssentials.join(', ')} - - Please add it manually in the addons array of your project's - .storybook/main.js|ts file. - ` - ); - } - - const rootMainJsTsPath = tree.exists('.storybook/main.js') - ? '.storybook/main.js' - : tree.exists('.storybook/main.ts') - ? '.storybook/main.ts' - : undefined; - - if (rootMainJsTsPath) { - const addonArrayOrEssentialsRemoved = - removeAddonEssentialsFromRootStorybook(tree, rootMainJsTsPath); - const storiesArrayRemoved = removeStoriesArrayFromRootIfEmpty( - tree, - rootMainJsTsPath - ); - - const removedRoot = removeRootConfig(tree, rootMainJsTsPath); - - if (removedRoot) { - // Logs are already printed in the removeRootConfig function - } else { - logger.info( - ` - We removed the ${ - addonArrayOrEssentialsRemoved === 'addons' - ? 'addons array ' - : '@storybook/addon-essentials addon ' - } - ${storiesArrayRemoved ? 'and the stories array ' : ''} - from the root .storybook/main.js|ts file. - ` - ); - } - } - - logger.info( - ` - Read more about our effort to deprecate the root .storybook folder here: - https://nx.dev/packages/storybook/documents/configuring-storybook - ` - ); - - await formatFiles(tree); -} - -function removeAddonEssentialsFromRootStorybook( - tree: Tree, - rootMainJsTsPath: string -): 'addons' | 'esssentials' | undefined { - let rootMainJsTs = tree.read(rootMainJsTsPath, 'utf-8'); - - const addonEssentials = tsquery.query( - rootMainJsTs, - 'StringLiteral:has([text="@storybook/addon-essentials"])' - )?.[0]; - - if (addonEssentials?.getText()?.length) { - const fullAddonsNode = tsquery.query( - rootMainJsTs, - 'PropertyAssignment:has([name="addons"])' - )?.[0]; - - const stringLiterals = tsquery.query(fullAddonsNode, 'StringLiteral'); - - if ( - stringLiterals?.length === 1 && - stringLiterals?.[0]?.getText() === `'@storybook/addon-essentials'` - ) { - rootMainJsTs = applyChangesToString(rootMainJsTs, [ - { - type: ChangeType.Delete, - start: fullAddonsNode.getStart(), - length: - rootMainJsTs[fullAddonsNode.getEnd()] === ',' - ? fullAddonsNode.getText().length + 1 - : fullAddonsNode.getText().length, - }, - ]); - tree.write(rootMainJsTsPath, rootMainJsTs); - - return 'addons'; - } else { - rootMainJsTs = applyChangesToString(rootMainJsTs, [ - { - type: ChangeType.Delete, - start: addonEssentials.getStart(), - length: - rootMainJsTs[addonEssentials.getEnd()] === ',' - ? addonEssentials.getText().length + 1 - : addonEssentials.getText().length, - }, - ]); - tree.write(rootMainJsTsPath, rootMainJsTs); - return 'esssentials'; - } - } -} - -function addAddonEssentialsToAllStorybooks(tree: Tree): string[] { - const projectsThatFailedTOAddAddonEssentials = []; - forEachExecutorOptions( - tree, - '@nrwl/storybook:build', - (options, projectName) => { - const failedToAddAddon = addAddon(tree, options, projectName); - if (failedToAddAddon) { - projectsThatFailedTOAddAddonEssentials.push(failedToAddAddon); - } - } - ); - - forEachExecutorOptions( - tree, - '@storybook/angular:build-storybook', - (options, projectName) => { - const failedToAddAddon = addAddon(tree, options, projectName); - if (failedToAddAddon) { - projectsThatFailedTOAddAddonEssentials.push(failedToAddAddon); - } - } - ); - return Array.from(new Set(projectsThatFailedTOAddAddonEssentials)); -} - -function addAddon(tree: Tree, options: {}, projectName: string): string { - const storybookDir = options?.['configDir']; - - if (storybookDir) { - const mainJsTsPath = tree.exists(`${storybookDir}/main.js`) - ? `${storybookDir}/main.js` - : tree.exists(`${storybookDir}/main.ts`) - ? `${storybookDir}/main.ts` - : undefined; - - let addedAddons = mainJsTsPath - ? transformMainJsTs(tree, mainJsTsPath) - : false; - - if ((storybookDir && !mainJsTsPath) || !addedAddons) { - return projectName; - } - } -} - -function transformMainJsTs(tree: Tree, mainJsTsPath: string): boolean { - let mainJsTs = tree.read(mainJsTsPath, 'utf-8'); - - const addonsArray = tsquery.query( - mainJsTs, - 'ArrayLiteralExpression:has(Identifier[name="addons"])' - )?.[0]; - - if (addonsArray?.getText()?.length) { - // If addons array does not contain @storybook/addon-essentials, add it - if (!addonsArray.getText().includes('@storybook/addon-essentials')) { - mainJsTs = applyChangesToString(mainJsTs, [ - { - type: ChangeType.Insert, - index: addonsArray.getStart() + 1, - text: `'@storybook/addon-essentials', `, - }, - ]); - tree.write(mainJsTsPath, mainJsTs); - return true; - } - return false; - } else { - // We will add the addons array after the stories array - // If I have a stories array, that's where my addons need to go - // And there's no config without stories - - const storiesArray = tsquery.query( - mainJsTs, - 'ArrayLiteralExpression:has(Identifier[name="stories"])' - )?.[0]; - - if (storiesArray?.getText()?.length) { - mainJsTs = applyChangesToString(mainJsTs, [ - { - type: ChangeType.Insert, - index: storiesArray.getEnd(), - text: `, addons: ['@storybook/addon-essentials']`, - }, - ]); - tree.write(mainJsTsPath, mainJsTs); - return true; - } else { - /** - * main.js has potentially a different structure - * sort of like this: - * rootMain.addons.push(' ...) - * rootMain.stories.push(' ...) - * Like in older versions of Nx - */ - - const { rootMainVariableName, importExpression } = - getRootMainVariableName(mainJsTs); - - // If there is a PropertyAccessExpression with the text rootMain.addons - // then check if it has addon-essentials, if not add it - const addonsPropertyAccessExpression = tsquery.query( - mainJsTs, - `PropertyAccessExpression:has([expression.name="${rootMainVariableName}"]):has([name="addons"])` - )?.[0]; - - if (rootMainVariableName && importExpression) { - if ( - addonsPropertyAccessExpression?.getText() === - `${rootMainVariableName}.addons.push` - ) { - const parentCallExpression = addonsPropertyAccessExpression.parent; - - // see if parentCallExpression contains a StringLiteral with the text '@storybook/addon-essentials' - const hasAddonEssentials = !!tsquery - .query( - parentCallExpression, - `StringLiteral:has([text="@storybook/addon-essentials"])` - )?.[0] - ?.getText(); - - if (!hasAddonEssentials) { - mainJsTs = applyChangesToString(mainJsTs, [ - { - type: ChangeType.Insert, - index: addonsPropertyAccessExpression.getEnd() + 1, - text: `'@storybook/addon-essentials', `, - }, - ]); - tree.write(mainJsTsPath, mainJsTs); - return true; - } - } else { - mainJsTs = applyChangesToString(mainJsTs, [ - { - type: ChangeType.Insert, - index: importExpression.getEnd() + 1, - text: `${rootMainVariableName}.addons.push('@storybook/addon-essentials');`, - }, - ]); - tree.write(mainJsTsPath, mainJsTs); - return true; - } - } - } - return false; - } -} - -function removeStoriesArrayFromRootIfEmpty( - tree: Tree, - rootMainJsTsPath: string -): boolean { - if (rootMainJsTsPath) { - let rootMainJsTs = tree.read(rootMainJsTsPath, 'utf-8'); - - const fullStoriesNode = tsquery.query( - rootMainJsTs, - 'PropertyAssignment:has([name="stories"])' - )?.[0]; - - if (!fullStoriesNode) { - return false; - } - - const stringLiterals = tsquery.query(fullStoriesNode, 'StringLiteral'); - - if (stringLiterals?.length === 0) { - rootMainJsTs = applyChangesToString(rootMainJsTs, [ - { - type: ChangeType.Delete, - start: fullStoriesNode.getStart(), - length: - rootMainJsTs[fullStoriesNode.getEnd()] === ',' - ? fullStoriesNode.getText().length + 1 - : fullStoriesNode.getText().length, - }, - ]); - tree.write(rootMainJsTsPath, rootMainJsTs); - return true; - } - } -} - -export function getRootMainVariableName(mainJsTs: string): { - rootMainVariableName: string; - importExpression: ts.Node; -} { - const requireVariableStatement = tsquery.query( - mainJsTs, - `VariableStatement:has(CallExpression:has(Identifier[name="require"]))` - ); - - let rootMainVariableName; - let importExpression; - - if (requireVariableStatement.length) { - importExpression = requireVariableStatement.find((statement) => { - const requireCallExpression = tsquery.query( - statement, - 'CallExpression:has(Identifier[name="require"])' - ); - return requireCallExpression?.[0]?.getText()?.includes('.storybook/main'); - }); - - if (importExpression) { - rootMainVariableName = tsquery - .query(importExpression, 'Identifier')?.[0] - ?.getText(); - } - } else { - const importDeclarations = tsquery.query(mainJsTs, 'ImportDeclaration'); - importExpression = importDeclarations.find((statement) => { - const stringLiteral = tsquery.query(statement, 'StringLiteral'); - return stringLiteral?.[0]?.getText()?.includes('.storybook/main'); - }); - - if (importExpression) { - rootMainVariableName = tsquery - .query(importExpression, 'ImportSpecifier')?.[0] - ?.getText(); - } - } - - return { - rootMainVariableName, - importExpression, - }; -} diff --git a/packages/storybook/src/migrations/update-15-7-0/remove-root-config.ts b/packages/storybook/src/migrations/update-15-7-0/remove-root-config.ts deleted file mode 100644 index 175d8995b1a81..0000000000000 --- a/packages/storybook/src/migrations/update-15-7-0/remove-root-config.ts +++ /dev/null @@ -1,312 +0,0 @@ -import { - applyChangesToString, - ChangeType, - logger, - StringChange, - Tree, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { getRootMainVariableName } from './add-addon-essentials-to-all'; -import ts = require('typescript'); - -/** - * The purpose of this migrator is to help users move away - * from the root .storybook/ configuration folder and files. - * - * This is the second part of the migrator. - * - * If the root main.js file is empty, then we can safely delete it - * and also remove all the references to it from the project-level - * Storybook configuration files. - * - * Point the user to a guide that explains how to all these things. - */ - -export function removeRootConfig( - tree: Tree, - rootMainJsTsPath: string -): boolean { - if (checkIfRootMainJsTsIsEmpty(tree, rootMainJsTsPath)) { - const hasRemainingRootMainJsReferences = removeImportFromAllFiles(tree); - tree.delete(rootMainJsTsPath); - logger.warn( - ` - We removed the root ${rootMainJsTsPath} file and we also - removed all it's imports from all project-level Storybook configuration files. - ` - ); - - if (hasRemainingRootMainJsReferences.length) { - logger.warn( - ` - However, there are still other references to the root .storybook/main.js|ts file - in the following files: - - ${hasRemainingRootMainJsReferences.join('\n')} - - Please remove them manually. - ` - ); - } - - return true; - } -} - -function removeImportFromAllFiles(tree: Tree): string[] { - const hasRemainingRootMainJsReferences = []; - forEachExecutorOptions(tree, '@nrwl/storybook:build', (options) => { - const hasRemainingReference = makeTheChanges(tree, options); - if (hasRemainingReference) { - hasRemainingRootMainJsReferences.push(hasRemainingReference); - } - }); - - forEachExecutorOptions( - tree, - '@storybook/angular:build-storybook', - (options) => { - const hasRemainingReference = makeTheChanges(tree, options); - if (hasRemainingReference) { - hasRemainingRootMainJsReferences.push(hasRemainingReference); - } - } - ); - return hasRemainingRootMainJsReferences; -} - -function makeTheChanges(tree: Tree, options: {}): string | undefined { - const storybookDir = options?.['configDir']; - - if (storybookDir) { - const mainJsTsPath = tree.exists(`${storybookDir}/main.js`) - ? `${storybookDir}/main.js` - : tree.exists(`${storybookDir}/main.ts`) - ? `${storybookDir}/main.ts` - : undefined; - - if (mainJsTsPath) { - let mainJsTs = tree.read(mainJsTsPath, 'utf-8'); - - const { rootMainVariableName, importExpression } = - getRootMainVariableName(mainJsTs); - - if (importExpression && rootMainVariableName) { - const changesToBeMade: StringChange[] = [ - { - type: ChangeType.Delete, - start: importExpression.getStart(), - length: importExpression.getText().length, - }, - ]; - - const spreadElements = tsquery.query( - mainJsTs, - `SpreadElement:has(Identifier[name="${rootMainVariableName}"])` - ); - spreadElements.forEach((spreadElement) => { - changesToBeMade.push({ - type: ChangeType.Delete, - start: spreadElement.getStart(), - length: - mainJsTs[spreadElement.getEnd()] === ',' - ? spreadElement.getText().length + 1 - : spreadElement.getText().length, - }); - }); - - const spreadAssignments = tsquery.query( - mainJsTs, - `SpreadAssignment:has(Identifier[name="${rootMainVariableName}"])` - ); - spreadAssignments.forEach((spreadAssignment) => { - changesToBeMade.push({ - type: ChangeType.Delete, - start: spreadAssignment.getStart(), - length: - mainJsTs[spreadAssignment.getEnd()] === ',' - ? spreadAssignment.getText().length + 1 - : spreadAssignment.getText().length, - }); - }); - - const findOtherRootMainUses = tsquery.query( - mainJsTs, - `Identifier[name="${rootMainVariableName}"]` - ); - - findOtherRootMainUses.forEach((otherRootMainUse) => { - /** - * This would be mainly to remove the legacy - * - * if (rootMain.webpackFinal) { - * config = await rootMain.webpackFinal(config, { configType }); - * } - */ - if ( - otherRootMainUse.parent.kind === - ts.SyntaxKind.PropertyAccessExpression && - otherRootMainUse.parent.parent?.kind === ts.SyntaxKind.IfStatement - ) { - changesToBeMade.push({ - type: ChangeType.Delete, - start: otherRootMainUse.parent.parent.getStart(), - length: otherRootMainUse.parent.parent.getText().length + 1, - }); - } - }); - - mainJsTs = applyChangesToString(mainJsTs, [...changesToBeMade]); - tree.write(mainJsTsPath, mainJsTs); - - if (hasMoreRootMainUses(tree, mainJsTsPath, rootMainVariableName)) { - if ( - checkIfUsesOldSyntaxAndUpdate( - tree, - mainJsTsPath, - rootMainVariableName - ) - ) { - return undefined; - } - return mainJsTsPath; - } - } - } - } -} - -function checkIfUsesOldSyntaxAndUpdate( - tree: Tree, - filePath: string, - rootMainVariableName: string -): boolean { - const mainJsTs = tree.read(filePath, 'utf-8'); - const changesToBeMade: StringChange[] = []; - const { stringArray: addonsArrayString, expressionToDelete: addonsToDelete } = - getPropertyArray('addons', mainJsTs, rootMainVariableName); - - const { - stringArray: storiesArrayString, - expressionToDelete: storiesToDelete, - } = getPropertyArray('stories', mainJsTs, rootMainVariableName); - - if (storiesToDelete) { - changesToBeMade.push(storiesToDelete); - } - if (addonsToDelete) { - changesToBeMade.push(addonsToDelete); - } - - if (addArrayToModuleExports('addons', mainJsTs, addonsArrayString)) { - changesToBeMade.push( - addArrayToModuleExports('addons', mainJsTs, addonsArrayString) - ); - } - - if (addArrayToModuleExports('stories', mainJsTs, storiesArrayString)) { - changesToBeMade.push( - addArrayToModuleExports('stories', mainJsTs, storiesArrayString) - ); - } - - if (changesToBeMade.length) { - tree.write(filePath, applyChangesToString(mainJsTs, changesToBeMade)); - return true; - } -} - -function addArrayToModuleExports( - propertyName: string, - mainJsTs: string, - arrayString: string -): StringChange { - if (!arrayString) { - return; - } - - const moduleExports = tsquery.query( - mainJsTs, - `PropertyAccessExpression:has([expression.name="module"]):has([name="exports"]):has([name="${propertyName}"])` - )?.[0]; - if (moduleExports) { - const parentBinaryExpression = moduleExports.parent; - const arrayExpression = tsquery.query( - parentBinaryExpression, - `ArrayLiteralExpression` - )?.[0]; - - return { - type: ChangeType.Insert, - index: arrayExpression.getStart() + 1, - text: arrayString, - }; - } else { - return { - type: ChangeType.Insert, - index: mainJsTs.length, - text: `module.exports.${propertyName} = [${arrayString}];\n`, - }; - } -} - -function getPropertyArray( - propertyName: string, - mainJsTs: string, - rootMainVariableName: string -): { stringArray: string; expressionToDelete: StringChange } { - const propertyAccessExpression = tsquery.query( - mainJsTs, - `PropertyAccessExpression:has([expression.name="${rootMainVariableName}"]):has([name="${propertyName}"])` - )?.[0]; - - if (propertyAccessExpression) { - if ( - propertyAccessExpression?.getText() === - `${rootMainVariableName}.${propertyName}.push` - ) { - const parentCallExpression = propertyAccessExpression.parent; - const stringPropertyArray = tsquery - .query(parentCallExpression, `StringLiteral`) - .map((stringLiteral) => stringLiteral?.getText()); - - return { - stringArray: `${stringPropertyArray.join(', ')}`, - expressionToDelete: { - type: ChangeType.Delete, - start: parentCallExpression.getStart(), - length: parentCallExpression.getText().length + 1, - }, - }; - } - } -} - -function hasMoreRootMainUses( - tree: Tree, - filePath: string, - rootMainVariableName: string -): boolean { - const mainJsTs = tree.read(filePath, 'utf-8'); - const findRemainingRootMainUses = tsquery.query( - mainJsTs, - `Identifier[name="${rootMainVariableName}"]` - ); - return findRemainingRootMainUses?.length > 0; -} - -function checkIfRootMainJsTsIsEmpty(tree: Tree, rootMainJsTsPath: string) { - const rootMainJsTs = tree.read(rootMainJsTsPath, 'utf-8'); - const mainConfigObject = tsquery.query( - rootMainJsTs, - 'ObjectLiteralExpression' - ); - - if ( - mainConfigObject?.length === 1 && - mainConfigObject[0]?.getText()?.replace(/\s/g, '') === '{}' - ) { - return true; - } -} diff --git a/packages/storybook/src/migrations/update-16-1-0/eslint-ignore-react-plugin.spec.ts b/packages/storybook/src/migrations/update-16-1-0/eslint-ignore-react-plugin.spec.ts index b222e60e5fb54..7cdae11d3cd53 100644 --- a/packages/storybook/src/migrations/update-16-1-0/eslint-ignore-react-plugin.spec.ts +++ b/packages/storybook/src/migrations/update-16-1-0/eslint-ignore-react-plugin.spec.ts @@ -6,7 +6,7 @@ import { updateJson, } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import * as variousProjects from '../update-15-7-0/test-configs/various-configs.json'; +import * as variousProjects from './test-configs/various-configs.json'; import eslintIgnoreReactPlugin from './eslint-ignore-react-plugin'; describe('Ignore @nx/react/plugins/storybook in Storybook eslint plugin', () => { diff --git a/packages/storybook/src/migrations/update-15-7-0/test-configs/various-configs.json b/packages/storybook/src/migrations/update-16-1-0/test-configs/various-configs.json similarity index 100% rename from packages/storybook/src/migrations/update-15-7-0/test-configs/various-configs.json rename to packages/storybook/src/migrations/update-16-1-0/test-configs/various-configs.json diff --git a/packages/vite/migrations.json b/packages/vite/migrations.json index cd874ecb5f6b7..800eb7be3fa05 100644 --- a/packages/vite/migrations.json +++ b/packages/vite/migrations.json @@ -1,23 +1,5 @@ { "generators": { - "update-vite-tsconfig-paths": { - "cli": "nx", - "version": "15.3.1-beta.0", - "description": "Remove projects property from vite-tsconfig-paths plugin in vite.config.ts files.", - "factory": "./src/migrations/update-15-3-1/update-vite-tsconfig-paths" - }, - "set-mode-in-configurations": { - "cli": "nx", - "version": "15.3.4-beta.0", - "description": "Set the mode in configurations to match the configurationName.", - "factory": "./src/migrations/update-15-3-4/set-mode-in-configuration" - }, - "update-test-path-placeholder-vars": { - "cli": "nx", - "version": "15.4.3-beta.0", - "description": "Update @nrwl/vite:test reportsDirectory and outputs properties to point to correct paths.", - "factory": "./src/migrations/update-15-4-3/update-report-directory" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -202,52 +184,6 @@ "alwaysAddToPackageJson": false } } - }, - "15.3.1-beta.0": { - "version": "15.3.1-beta.0", - "packages": { - "vite-tsconfig-paths": { - "version": "4.0.0", - "alwaysAddToPackageJson": false - } - } - }, - "15.3.4-beta.0": { - "version": "15.3.4-beta.0", - "packages": { - "vite": { - "version": "^4.0.1", - "alwaysAddToPackageJson": false - }, - "vite-tsconfig-paths": { - "version": "^4.0.2", - "alwaysAddToPackageJson": false - }, - "vitest": { - "version": "^0.25.8", - "alwaysAddToPackageJson": false - }, - "vite-plugin-dts": { - "version": "~1.7.1", - "alwaysAddToPackageJson": false - }, - "@vitejs/plugin-react": { - "version": "^3.0.0", - "alwaysAddToPackageJson": false - }, - "@vitest/coverage-c8": { - "version": "^0.25.8", - "alwaysAddToPackageJson": false - }, - "@vitest/ui": { - "version": "^0.25.8", - "alwaysAddToPackageJson": false - }, - "@vitest/coverage-istanbul": { - "version": "^0.25.8", - "alwaysAddToPackageJson": false - } - } } } } diff --git a/packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.spec.ts b/packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.spec.ts deleted file mode 100644 index 39def737f3b2e..0000000000000 --- a/packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { addDependenciesToPackageJson, Tree } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { mockViteReactAppGenerator } from '../../utils/test-utils'; -import { removeProjectsFromViteTsConfigPaths } from './update-vite-tsconfig-paths'; - -describe('remove projects from vite-tsconfig-paths', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - mockViteReactAppGenerator(tree); - const existing = 'existing'; - const existingVersion = '1.0.0'; - addDependenciesToPackageJson( - tree, - { 'vite-tsconfig-paths': '^3.6.0', [existing]: existingVersion }, - { [existing]: existingVersion } - ); - }); - - it('should remove the projects attribute from vite-tsconfig-paths', async () => { - await removeProjectsFromViteTsConfigPaths(tree); - const appFileContent = tree.read( - 'apps/my-test-react-vite-app/vite.config.ts', - 'utf-8' - ); - const file = tsquery.ast(appFileContent); - - expect(file.getText().includes('tsconfig.base.json')).toBeFalsy(); - expect(file.getText().includes('projects')).toBeFalsy(); - }); -}); diff --git a/packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.ts b/packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.ts deleted file mode 100644 index 196b4ca531f99..0000000000000 --- a/packages/vite/src/migrations/update-15-3-1/update-vite-tsconfig-paths.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { - applyChangesToString, - ChangeType, - formatFiles, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { findNodes } from '@nx/js'; -import { normalizeViteConfigFilePathWithTree } from '../../utils/generator-utils'; -import ts = require('typescript'); - -export async function removeProjectsFromViteTsConfigPaths(tree: Tree) { - findAllProjectsWithViteConfig(tree); - await formatFiles(tree); -} - -export default removeProjectsFromViteTsConfigPaths; - -function findAllProjectsWithViteConfig(tree: Tree): void { - forEachExecutorOptions(tree, '@nrwl/vite:build', (options, project) => { - const projectConfiguration = readProjectConfiguration(tree, project); - const viteConfig = normalizeViteConfigFilePathWithTree( - tree, - projectConfiguration.root, - options?.['configFile'] - ); - if (viteConfig) { - const appFileContent = tree.read(viteConfig, 'utf-8'); - const file = tsquery.ast(appFileContent); - let newContents = appFileContent; - const defineConfig = tsquery.query( - file, - 'CallExpression:has(Identifier[name="defineConfig"])' - ); - let startOfProjects, endOfProjects; - - defineConfig?.[0] - ?.getChildren() - .forEach((defineConfigContentNode: any) => { - // Make sure it's the one we are looking for - // We cannot assume that it's called tsConfigPaths - // So make sure it includes `projects` and `root` - if ( - defineConfigContentNode.getText().includes('projects') && - defineConfigContentNode.getText().includes('root') - ) { - findNodes(defineConfigContentNode, [ - ts.SyntaxKind.PropertyAssignment, - ]).forEach((nodePA) => { - if (nodePA.getText().startsWith('projects')) { - startOfProjects = nodePA.getStart(); - endOfProjects = nodePA.getEnd(); - } - }); - } - }); - - if (startOfProjects && endOfProjects) { - newContents = applyChangesToString(newContents, [ - { - type: ChangeType.Delete, - start: startOfProjects, - length: endOfProjects - startOfProjects + 1, - }, - ]); - tree.write(viteConfig, newContents); - } - } - }); -} diff --git a/packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.spec.ts b/packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.spec.ts deleted file mode 100644 index 621bd0595c1e6..0000000000000 --- a/packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { readProjectConfiguration, Tree } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { mockViteReactAppGenerator } from '../../utils/test-utils'; -import { setModeInConfiguration } from './set-mode-in-configuration'; - -describe('set mode in configuration object', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - mockViteReactAppGenerator(tree); - }); - - it('should set the mode to be the configuration name and preserve other settings', async () => { - await setModeInConfiguration(tree); - - const projectConfig = readProjectConfiguration( - tree, - 'my-test-react-vite-app' - ); - - expect(projectConfig.targets.build.configurations.production.mode).toEqual( - 'production' - ); - - expect(projectConfig.targets.build.configurations.ssr.mode).toEqual('ssr'); - expect(projectConfig.targets.build.configurations.ssr.ssr).toBeTruthy(); - expect( - projectConfig.targets.build.configurations.ssr['my-other-setting'] - ).toBe('my-other-value'); - }); -}); diff --git a/packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.ts b/packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.ts deleted file mode 100644 index fb3ad6e0d42bf..0000000000000 --- a/packages/vite/src/migrations/update-15-3-4/set-mode-in-configuration.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - formatFiles, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; - -export async function setModeInConfiguration(tree: Tree) { - forAllProjectsUsingViteAddMode(tree); - await formatFiles(tree); -} - -export default setModeInConfiguration; - -function forAllProjectsUsingViteAddMode(tree: Tree): void { - forEachExecutorOptions( - tree, - '@nrwl/vite:build', - (_options, projectName, targetName, configuration) => { - if (!configuration) { - return; - } - - const projectConfiguration = readProjectConfiguration(tree, projectName); - projectConfiguration.targets[targetName].configurations[ - configuration - ].mode ??= configuration; - - updateProjectConfiguration(tree, projectName, { - ...projectConfiguration, - }); - } - ); -} diff --git a/packages/vite/src/migrations/update-15-4-3/update-report-directory.spec.ts b/packages/vite/src/migrations/update-15-4-3/update-report-directory.spec.ts deleted file mode 100644 index 511fa829dad25..0000000000000 --- a/packages/vite/src/migrations/update-15-4-3/update-report-directory.spec.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { updateReportDirectoryPlaceholders } from './update-report-directory'; - -describe('Update Report Directory Vitest Migration', () => { - let tree: Tree; - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should migrate', () => { - addVitestProjects(tree, { name: 'project' }); - - updateReportDirectoryPlaceholders(tree); - expect(readProjectConfiguration(tree, 'project-one').targets) - .toMatchInlineSnapshot(` - { - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "../../coverge/packages/project-one", - }, - "outputs": [ - "coverage/packages/project-one", - ], - }, - } - `); - expect(readProjectConfiguration(tree, 'project-two').targets) - .toMatchInlineSnapshot(` - { - "custom-test": { - "configurations": { - "ci": { - "reportsDirectory": "coverge/project-two", - }, - }, - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - }, - "outputs": [ - "coverage/project-two", - "dist/coverage/else.txt", - ], - }, - "test": { - "executor": "@nrwl/vite:test", - "options": { - "passWithNoTests": true, - "reportsDirectory": "coverge/project-two", - }, - }, - } - `); - }); - it('should be idempotent', () => { - addVitestProjects(tree, { name: 'project' }); - - const expectedProjectOneConfig = { - test: { - outputs: ['coverage/packages/project-one'], - executor: '@nrwl/vite:test', - options: { - reportsDirectory: '../../coverge/packages/project-one', - passWithNoTests: true, - }, - }, - }; - - const expectedProjectTwoConfig = { - 'custom-test': { - executor: '@nrwl/vite:test', - outputs: ['coverage/project-two', 'dist/coverage/else.txt'], - options: { - passWithNoTests: true, - }, - configurations: { - ci: { - reportsDirectory: 'coverge/project-two', - }, - }, - }, - test: { - executor: '@nrwl/vite:test', - options: { - reportsDirectory: 'coverge/project-two', - passWithNoTests: true, - }, - }, - }; - - updateReportDirectoryPlaceholders(tree); - const projOneConfig = readProjectConfiguration(tree, 'project-one'); - expect(projOneConfig.targets).toEqual(expectedProjectOneConfig); - const projTwoConfig = readProjectConfiguration(tree, 'project-two'); - expect(projTwoConfig.targets).toEqual(expectedProjectTwoConfig); - }); -}); - -function addVitestProjects(tree: Tree, options: { name: string }) { - addProjectConfiguration(tree, options.name + '-one', { - name: options.name + '-one', - sourceRoot: `packages/${options.name}-one/src`, - root: `packages/${options.name}-one`, - targets: { - test: { - outputs: ['{projectRoot}/coverage'], - executor: '@nrwl/vite:test', - options: { - reportsDirectory: '{workspaceRoot}/coverge/{projectRoot}', - passWithNoTests: true, - }, - }, - }, - }); - addProjectConfiguration(tree, options.name + '-two', { - name: options.name + '-two', - sourceRoot: 'src', - root: '.', - targets: { - 'custom-test': { - executor: '@nrwl/vite:test', - outputs: ['{projectRoot}/coverage', 'dist/coverage/else.txt'], - options: { - passWithNoTests: true, - }, - configurations: { - ci: { - reportsDirectory: '{workspaceRoot}/coverge/{projectRoot}', - }, - }, - }, - test: { - executor: '@nrwl/vite:test', - options: { - reportsDirectory: '{workspaceRoot}/coverge/{projectRoot}', - passWithNoTests: true, - }, - }, - }, - }); -} diff --git a/packages/vite/src/migrations/update-15-4-3/update-report-directory.ts b/packages/vite/src/migrations/update-15-4-3/update-report-directory.ts deleted file mode 100644 index 66d0c02e3e8b4..0000000000000 --- a/packages/vite/src/migrations/update-15-4-3/update-report-directory.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - getProjects, - offsetFromRoot, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { VitestExecutorOptions } from '../../executors/test/schema'; - -export function updateReportDirectoryPlaceholders(tree: Tree) { - const projects = getProjects(tree); - forEachExecutorOptions( - tree, - '@nrwl/vite:test', - (options, projectName, targetName, configName) => { - const projectConfig = projects.get(projectName); - const coverageOutput = - projectConfig.root === '.' ? projectName : projectConfig.root; - - if (options.reportsDirectory) { - options.reportsDirectory = options.reportsDirectory - .replace( - '{workspaceRoot}/', - projectConfig.root === '.' ? '' : offsetFromRoot(projectConfig.root) - ) - .replace('{projectRoot}', coverageOutput); - if (configName) { - projectConfig.targets[targetName].configurations[configName] = - options; - } else { - projectConfig.targets[targetName].options = options; - } - if (projectConfig.targets[targetName].outputs) { - projectConfig.targets[targetName].outputs = projectConfig.targets[ - targetName - ].outputs.map((output) => - output.replace( - '{projectRoot}/coverage', - `coverage/${coverageOutput}` - ) - ); - } - updateProjectConfiguration(tree, projectName, projectConfig); - } - } - ); -} - -export default updateReportDirectoryPlaceholders; diff --git a/packages/web/migrations.json b/packages/web/migrations.json index 9e3d86ff0653c..7c71d46c9081d 100644 --- a/packages/web/migrations.json +++ b/packages/web/migrations.json @@ -1,29 +1,5 @@ { "generators": { - "add-babel-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Adds babel.config.json to the hash of all tasks", - "factory": "./src/migrations/update-15-0-0/add-babel-inputs" - }, - "update-rollup-executor": { - "cli": "nx", - "version": "15.0.0-beta.1", - "description": "Update usages of rollup executors to @nrwl/rollup", - "factory": "./src/migrations/update-15-0-0/update-rollup-executor" - }, - "update-babel-preset": { - "cli": "nx", - "version": "15.5.4-beta.0", - "description": "Update `@nrwl/web/babel` preset to `@nrwl/js/babel` for projects that have a .babelrc file.", - "factory": "./src/migrations/update-15-5-4/update-babel-preset" - }, - "add-dropped-dependencies": { - "cli": "nx", - "version": "15.9.1", - "description": "Add @nrwl/linter, @nrwl/cypress, @nrwl/jest, @nrwl/rollup if they are used", - "factory": "./src/migrations/update-15-9-1/add-dropped-dependencies" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", diff --git a/packages/web/src/migrations/update-15-0-0/add-babel-inputs.spec.ts b/packages/web/src/migrations/update-15-0-0/add-babel-inputs.spec.ts deleted file mode 100644 index 3ac51f6d23033..0000000000000 --- a/packages/web/src/migrations/update-15-0-0/add-babel-inputs.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { readNxJson, Tree, updateNxJson } from '@nx/devkit'; -import addBabelInputs from './add-babel-inputs'; - -describe('15.0.0 migration (add-babel-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add babel.config.json to sharedGlobals', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.json', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.json", - ], - }, - } - `); - }); - - it('should add babel.config.js', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.js', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.js", - ], - }, - } - `); - }); -}); diff --git a/packages/web/src/migrations/update-15-0-0/add-babel-inputs.ts b/packages/web/src/migrations/update-15-0-0/add-babel-inputs.ts deleted file mode 100644 index aa7e721076fe2..0000000000000 --- a/packages/web/src/migrations/update-15-0-0/add-babel-inputs.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { formatFiles, Tree } from '@nx/devkit'; -import { addBabelInputs } from '@nx/js/src/utils/add-babel-inputs'; - -export default async function (tree: Tree) { - addBabelInputs(tree); - await formatFiles(tree); -} diff --git a/packages/web/src/migrations/update-15-0-0/update-rollup-executor.spec.ts b/packages/web/src/migrations/update-15-0-0/update-rollup-executor.spec.ts deleted file mode 100644 index f52bb2b714280..0000000000000 --- a/packages/web/src/migrations/update-15-0-0/update-rollup-executor.spec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { addProjectConfiguration, readProjectConfiguration } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; - -import update from './update-rollup-executor'; - -describe('Migration: @nrwl/rollup', () => { - it(`should update usage of rollup executor`, async () => { - let tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'mylib', { - root: 'libs/mylib', - sourceRoot: 'libs/mylib/src', - projectType: 'library', - targets: { - build: { - executor: '@nrwl/web:rollup', - options: {}, - }, - }, - }); - await update(tree); - - expect(readProjectConfiguration(tree, 'mylib')).toEqual({ - $schema: '../../node_modules/nx/schemas/project-schema.json', - name: 'mylib', - root: 'libs/mylib', - sourceRoot: 'libs/mylib/src', - projectType: 'library', - targets: { - build: { - executor: '@nrwl/rollup:rollup', - options: {}, - }, - }, - }); - }); - - it(`should replace umd with cjs`, async () => { - let tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - - addProjectConfiguration(tree, 'lib1', { - root: 'libs/lib1', - sourceRoot: 'libs/lib1/src', - projectType: 'library', - targets: { - build: { - executor: '@nrwl/web:rollup', - options: { - formats: ['umd'], - }, - }, - }, - }); - addProjectConfiguration(tree, 'lib2', { - root: 'libs/lib2', - sourceRoot: 'libs/lib2/src', - projectType: 'library', - targets: { - build: { - executor: '@nrwl/rollup:rollup', - options: { - formats: ['esm', 'cjs', 'umd'], - }, - }, - }, - }); - - await update(tree); - - expect(readProjectConfiguration(tree, 'lib1')).toEqual({ - $schema: '../../node_modules/nx/schemas/project-schema.json', - name: 'lib1', - root: 'libs/lib1', - sourceRoot: 'libs/lib1/src', - projectType: 'library', - targets: { - build: { - executor: '@nrwl/rollup:rollup', - options: { - formats: ['cjs'], - }, - }, - }, - }); - expect(readProjectConfiguration(tree, 'lib2')).toEqual({ - $schema: '../../node_modules/nx/schemas/project-schema.json', - name: 'lib2', - root: 'libs/lib2', - sourceRoot: 'libs/lib2/src', - projectType: 'library', - targets: { - build: { - executor: '@nrwl/rollup:rollup', - options: { - formats: ['esm', 'cjs'], - }, - }, - }, - }); - }); -}); diff --git a/packages/web/src/migrations/update-15-0-0/update-rollup-executor.ts b/packages/web/src/migrations/update-15-0-0/update-rollup-executor.ts deleted file mode 100644 index 723bcb73d172d..0000000000000 --- a/packages/web/src/migrations/update-15-0-0/update-rollup-executor.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - formatFiles, - getProjects, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; - -export default async function update(host: Tree) { - const projects = getProjects(host); - - for (const [name, config] of projects.entries()) { - let updated = false; - - if (config?.targets?.build?.executor === '@nrwl/web:rollup') { - config.targets.build.executor = '@nrwl/rollup:rollup'; - updated = true; - } - - if (config?.targets?.build?.options?.formats?.includes('umd')) { - config.targets.build.options.formats = - config.targets.build.options.formats.reduce((acc, x) => { - const format = x === 'umd' ? 'cjs' : x; - - if (format === 'cjs') { - if (!acc.includes('cjs')) acc.push(format); - } else { - acc.push(format); - } - - return acc; - }, []); - - updated = true; - } - - if (updated) { - updateProjectConfiguration(host, name, config); - } - } - - await formatFiles(host); -} diff --git a/packages/web/src/migrations/update-15-5-4/update-babel-preset.spec.ts b/packages/web/src/migrations/update-15-5-4/update-babel-preset.spec.ts deleted file mode 100644 index 1de235709f7f3..0000000000000 --- a/packages/web/src/migrations/update-15-5-4/update-babel-preset.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { addProjectConfiguration, readJson, Tree, writeJson } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; - -import update from './update-babel-preset'; - -describe('update-babel-preset', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace(); - }); - - it('should update preset with options', async () => { - addProjectConfiguration(tree, 'demo', { - root: 'demo', - }); - writeJson(tree, 'demo/.babelrc', { - presets: [ - '@acme/foo', - [ - '@nrwl/web/babel', - { - useBuiltIns: 'usage', - }, - ], - '@acme/bar', - ], - }); - - await update(tree); - - const result = readJson(tree, 'demo/.babelrc'); - expect(result).toEqual({ - presets: [ - '@acme/foo', - [ - '@nrwl/js/babel', - { - useBuiltIns: 'usage', - }, - ], - '@acme/bar', - ], - }); - }); - - it('should update preset without options', async () => { - addProjectConfiguration(tree, 'demo', { - root: 'demo', - }); - writeJson(tree, 'demo/.babelrc', { - presets: ['@acme/foo', '@nrwl/web/babel', '@acme/bar'], - }); - - await update(tree); - - const result = readJson(tree, 'demo/.babelrc'); - expect(result).toEqual({ - presets: ['@acme/foo', '@nrwl/js/babel', '@acme/bar'], - }); - }); -}); diff --git a/packages/web/src/migrations/update-15-5-4/update-babel-preset.ts b/packages/web/src/migrations/update-15-5-4/update-babel-preset.ts deleted file mode 100644 index a5955cb7b6f5e..0000000000000 --- a/packages/web/src/migrations/update-15-5-4/update-babel-preset.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - readJson, - writeJson, - Tree, - addDependenciesToPackageJson, - getProjects, - joinPathFragments, -} from '@nx/devkit'; -import { nxVersion } from '../../utils/versions'; - -/* Updates @nrwl/web/babel to @nrwl/js/babel because web package is no longer necessary to use webpack/rollup + babel. */ -export default async function update(tree: Tree) { - // Add `@nrwl/js` in case it was missing before. - addDependenciesToPackageJson( - tree, - {}, - { - '@nrwl/js': nxVersion, - } - ); - - const projects = getProjects(tree); - - projects.forEach((config, name) => { - const babelrcPath = joinPathFragments(config.root, '.babelrc'); - - if (!tree.exists(babelrcPath)) return; - - const babelrc = readJson(tree, babelrcPath); - const idx = babelrc?.presets?.findIndex((p) => - typeof p === 'string' - ? p === '@nrwl/web/babel' - : p[0] === '@nrwl/web/babel' - ); - - if (idx === -1) return; - - const preset = babelrc.presets[idx]; - if (typeof preset === 'string') { - babelrc.presets.splice(idx, 1, '@nrwl/js/babel'); - } else if (Array.isArray(preset)) { - babelrc.presets.splice(idx, 1, ['@nrwl/js/babel', preset[1]]); - } - - writeJson(tree, babelrcPath, babelrc); - }); -} diff --git a/packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.spec.ts b/packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.spec.ts deleted file mode 100644 index 7b34dcd24edbe..0000000000000 --- a/packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.spec.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { - addProjectConfiguration, - readJson, - Tree, - updateNxJson, -} from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; - -import addDroppedDependencies from './add-dropped-dependencies'; - -describe('addDroppedDependencies', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace(); - - addProjectConfiguration(tree, 'project-with-no-targets', { - root: 'proj-with-no-targets', - }); - addProjectConfiguration(tree, 'project-with-command', { - root: 'proj-with-command', - targets: { - run: { - command: 'echo hi', - }, - }, - }); - }); - - it('should add rollup', async () => { - addProjectConfiguration(tree, 'rollup-project', { - root: 'rollup-proj', - targets: { - build: { - executor: '@nrwl/rollup:rollup', - options: {}, - }, - }, - }); - - await addDroppedDependencies(tree); - - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/rollup'] - ).toBeDefined(); - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/cypress'] - ).not.toBeDefined(); - }); - - it('should add cypress', async () => { - addProjectConfiguration(tree, 'cypress-project', { - root: 'cypress-proj', - targets: { - build: { - executor: '@nrwl/cypress:cypress', - options: {}, - }, - }, - }); - - await addDroppedDependencies(tree); - - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/cypress'] - ).toBeDefined(); - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/rollup'] - ).not.toBeDefined(); - }); - - it('should add linter', async () => { - addProjectConfiguration(tree, 'linter-project', { - root: 'linter-proj', - targets: { - build: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - }, - }); - - await addDroppedDependencies(tree); - - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/linter'] - ).toBeDefined(); - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/cypress'] - ).not.toBeDefined(); - }); - - it('should add a dependency if it is used in nx.json', async () => { - updateNxJson(tree, { - targetDefaults: { - build: { - executor: '@nrwl/linter:eslint', - options: {}, - }, - test: { - options: {}, - }, - }, - }); - - await addDroppedDependencies(tree); - - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/linter'] - ).toBeDefined(); - expect( - readJson(tree, 'package.json').devDependencies['@nrwl/cypress'] - ).not.toBeDefined(); - }); -}); diff --git a/packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.ts b/packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.ts deleted file mode 100644 index e8a6c1f93cb72..0000000000000 --- a/packages/web/src/migrations/update-15-9-1/add-dropped-dependencies.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - addDependenciesToPackageJson, - formatFiles, - getProjects, - NX_VERSION, - readNxJson, - Tree, -} from '@nx/devkit'; - -export default async function addDroppedDependencies(tree: Tree) { - const devDependencies = {}; - const droppedDependencies = [ - '@nrwl/linter', - '@nrwl/cypress', - '@nrwl/jest', - '@nrwl/rollup', - ]; - const projects = getProjects(tree); - - for (const [_, projectConfiguration] of projects) { - for (const [_, targetConfiguration] of Object.entries( - projectConfiguration.targets ?? {} - )) { - for (const droppedDependency of droppedDependencies) { - if ( - targetConfiguration?.['executor']?.startsWith(droppedDependency + ':') - ) { - devDependencies[droppedDependency] = NX_VERSION; - } - } - } - } - - const nxJson = readNxJson(tree); - - for (const [_, targetConfiguration] of Object.entries( - nxJson?.targetDefaults ?? {} - )) { - for (const droppedDependency of droppedDependencies) { - if ( - targetConfiguration?.['executor']?.startsWith(droppedDependency + ':') - ) { - devDependencies[droppedDependency] = NX_VERSION; - } - } - } - - if (Object.keys(devDependencies).length > 0) { - addDependenciesToPackageJson(tree, {}, devDependencies); - } - - await formatFiles(tree); -} diff --git a/packages/webpack/migrations.json b/packages/webpack/migrations.json index a6e0ac09cf90c..02ac19f56038b 100644 --- a/packages/webpack/migrations.json +++ b/packages/webpack/migrations.json @@ -1,29 +1,5 @@ { "generators": { - "add-babel-inputs": { - "cli": "nx", - "version": "15.0.0-beta.0", - "description": "Adds babel.config.json to the hash of all tasks", - "factory": "./src/migrations/update-15-0-0/add-babel-inputs" - }, - "remove-es2015-polyfills-option": { - "cli": "nx", - "version": "15.4.5-beta.0", - "description": "Removes es2015Polyfills option since legacy browsers are no longer supported.", - "factory": "./src/migrations/update-15-4-5/remove-es2015-polyfills-option" - }, - "webpack-config-setup": { - "cli": "nx", - "version": "15.6.3-beta.0", - "description": "Creates or updates webpack.config.js file with the new options for webpack.", - "factory": "./src/migrations/update-15-6-3/webpack-config-setup" - }, - "add-babelUpwardRootMode-flag": { - "cli": "nx", - "version": "15.7.2-beta.0", - "description": "Add the babelUpwardRootMode option to the build executor options.", - "factory": "./src/migrations/update-15-7-2/add-babelUpwardRootMode-flag" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", diff --git a/packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.spec.ts b/packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.spec.ts deleted file mode 100644 index 3ac51f6d23033..0000000000000 --- a/packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { readNxJson, Tree, updateNxJson } from '@nx/devkit'; -import addBabelInputs from './add-babel-inputs'; - -describe('15.0.0 migration (add-babel-inputs)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add babel.config.json to sharedGlobals', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.json', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.json", - ], - }, - } - `); - }); - - it('should add babel.config.js', async () => { - updateNxJson(tree, { - namedInputs: { - default: ['{projectRoot}/**/*', 'sharedGlobals'], - sharedGlobals: [], - production: ['default'], - }, - }); - tree.write('babel.config.js', ''); - - await addBabelInputs(tree); - - const updated = readNxJson(tree); - expect(updated).toMatchInlineSnapshot(` - { - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "sharedGlobals", - ], - "production": [ - "default", - ], - "sharedGlobals": [ - "{workspaceRoot}/babel.config.js", - ], - }, - } - `); - }); -}); diff --git a/packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.ts b/packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.ts deleted file mode 100644 index aa7e721076fe2..0000000000000 --- a/packages/webpack/src/migrations/update-15-0-0/add-babel-inputs.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { formatFiles, Tree } from '@nx/devkit'; -import { addBabelInputs } from '@nx/js/src/utils/add-babel-inputs'; - -export default async function (tree: Tree) { - addBabelInputs(tree); - await formatFiles(tree); -} diff --git a/packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.spec.ts b/packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.spec.ts deleted file mode 100644 index b3b207dd1fc20..0000000000000 --- a/packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import update from './remove-es2015-polyfills-option'; - -describe('15.4.5 migration (remove es2015-polyfills)', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should update all executors using @nrwl/webpack:webpack and es2015Polyfills option', async () => { - addProjectConfiguration(tree, 'app1', { - root: 'app1', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - es2015Polyfills: 'app1/polyfills.ts', - }, - }, - }, - }); - addProjectConfiguration(tree, 'app2', { - root: 'app2', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - es2016Polyfills: 'app2/polyfills.ts', - }, - }, - }, - }); - addProjectConfiguration(tree, 'app3', { - root: 'app3', - targets: { - custom: { - executor: '@foo/bar:faz', - options: { - es2015Polyfills: 'app3/polyfills.ts', - }, - }, - }, - }); - - await update(tree); - - expect( - readProjectConfiguration(tree, 'app1').targets.build.options - .es2015Polyfills - ).toBeUndefined(); - expect( - readProjectConfiguration(tree, 'app2').targets.custom.options - .es2015Polyfills - ).toBeUndefined(); - // Another executor, left intact. - expect( - readProjectConfiguration(tree, 'app3').targets.custom.options - .es2015Polyfills - ).toEqual('app3/polyfills.ts'); - }); -}); diff --git a/packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.ts b/packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.ts deleted file mode 100644 index b1eb766343744..0000000000000 --- a/packages/webpack/src/migrations/update-15-4-5/remove-es2015-polyfills-option.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { getProjects, Tree, updateProjectConfiguration } from '@nx/devkit'; - -export default async function (tree: Tree) { - const projects = getProjects(tree); - projects.forEach((p) => { - let shouldUpdate = false; - - Object.entries(p.targets).forEach(([name, config]) => { - if ( - p.targets?.[name]?.executor === '@nrwl/webpack:webpack' && - p.targets?.[name]?.options.es2015Polyfills - ) { - delete p.targets?.[name]?.options.es2015Polyfills; - shouldUpdate = true; - } - }); - - if (shouldUpdate) { - updateProjectConfiguration(tree, p.name, p); - } - }); -} diff --git a/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap b/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap deleted file mode 100644 index 6452733bf4409..0000000000000 --- a/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap +++ /dev/null @@ -1,57 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`15.6.3 migration (setup webpack.config file) should create webpack.config.js for projects that do not have one 1`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); - -// Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; -}); -" -`; - -exports[`15.6.3 migration (setup webpack.config file) should create webpack.config.js for projects that do not have one 2`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); - -// Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; -}); -" -`; - -exports[`15.6.3 migration (setup webpack.config file) should rename existing webpack.config file and create new one that requires it 1`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); - -// Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config, { options, context }) => { - // Note: This was added by an Nx migration. - // You should consider inlining the logic into this file. - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return require('./webpack.config.old.js')(config, context); -}); -" -`; - -exports[`15.6.3 migration (setup webpack.config file) should rename existing webpack.config file and create new one that requires it 3`] = ` -"const { composePlugins, withNx } = require('@nrwl/webpack'); - -// Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config, { options, context }) => { - // Note: This was added by an Nx migration. - // You should consider inlining the logic into this file. - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return require('./webpack.something.old.ts')(config, context); -}); -" -`; diff --git a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts b/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts deleted file mode 100644 index 8e92a5079bd78..0000000000000 --- a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import webpackConfigSetup from './webpack-config-setup'; - -describe('15.6.3 migration (setup webpack.config file)', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should create webpack.config.js for projects that do not have one', async () => { - addProjectConfiguration(tree, 'app1', { - root: 'apps/app1', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: {}, - }, - }, - }); - addProjectConfiguration(tree, 'app2', { - root: 'apps/app2', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: {}, - }, - }, - }); - - await webpackConfigSetup(tree); - - expect(tree.read('apps/app1/webpack.config.js', 'utf-8')).toMatchSnapshot(); - expect(tree.read('apps/app2/webpack.config.js', 'utf-8')).toMatchSnapshot(); - }); - - it('should rename existing webpack.config file and create new one that requires it', async () => { - addProjectConfiguration(tree, 'app3', { - root: 'apps/app3', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: 'apps/app3/webpack.config.js', - }, - }, - }, - }); - tree.write('apps/app3/webpack.config.js', 'some content'); - - addProjectConfiguration(tree, 'app4', { - root: 'apps/app4', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: 'some/random/path/webpack.something.ts', - }, - }, - }, - }); - tree.write('some/random/path/webpack.something.ts', 'some content'); - - await webpackConfigSetup(tree); - - expect(tree.read('apps/app3/webpack.config.js', 'utf-8')).toMatchSnapshot(); - expect( - tree.read('apps/app3/webpack.config.old.js', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - - expect( - tree.read('some/random/path/webpack.something.ts', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read('some/random/path/webpack.something.old.ts', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - }); - - it('should update the project configuration - executor options', async () => { - addProjectConfiguration(tree, 'app1', { - root: 'apps/app1', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: {}, - }, - }, - }); - addProjectConfiguration(tree, 'app2', { - root: 'apps/app2', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: {}, - }, - }, - }); - - addProjectConfiguration(tree, 'app3', { - root: 'apps/app3', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: 'apps/app3/webpack.config.js', - }, - }, - }, - }); - - tree.write('apps/app3/webpack.config.js', 'some content'); - - addProjectConfiguration(tree, 'app4', { - root: 'apps/app4', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: 'some/random/path/webpack.something.ts', - }, - }, - }, - }); - tree.write('some/random/path/webpack.something.ts', 'some content'); - - await webpackConfigSetup(tree); - - expect( - readProjectConfiguration(tree, 'app1').targets.build.options.webpackConfig - ).toBe('apps/app1/webpack.config.js'); - expect( - readProjectConfiguration(tree, 'app2').targets.custom.options - .webpackConfig - ).toBe('apps/app2/webpack.config.js'); - - expect( - readProjectConfiguration(tree, 'app3').targets.custom.options - .webpackConfig - ).toBe('apps/app3/webpack.config.js'); - - expect( - readProjectConfiguration(tree, 'app4').targets.custom.options - .webpackConfig - ).toBe('some/random/path/webpack.something.ts'); - - expect( - readProjectConfiguration(tree, 'app1').targets.build.options - .isolatedConfig - ).toBeTruthy(); - expect( - readProjectConfiguration(tree, 'app2').targets.custom.options - .isolatedConfig - ).toBeTruthy(); - - expect( - readProjectConfiguration(tree, 'app3').targets.custom.options - .isolatedConfig - ).toBeTruthy(); - - expect( - readProjectConfiguration(tree, 'app4').targets.custom.options - .isolatedConfig - ).toBeTruthy(); - }); - - it('should not do anything if isolatedConfig is true', async () => { - addProjectConfiguration(tree, 'app5', { - root: 'apps/app5', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - isolatedConfig: true, - }, - }, - }, - }); - - await webpackConfigSetup(tree); - - expect(tree.exists('apps/app5/webpack.config.js')).toBeFalsy(); - }); - - it('should not do anything if project is react', async () => { - addProjectConfiguration(tree, 'app6', { - root: 'apps/app6', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: '@nrwl/react/plugins/webpack', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'app7', { - root: 'apps/app7', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/app7/src/main.tsx', - }, - }, - }, - }); - - await webpackConfigSetup(tree); - - expect(tree.exists('apps/app6/webpack.config.js')).toBeFalsy(); - expect(tree.exists('apps/app7/webpack.config.js')).toBeFalsy(); - }); - - it('should migrate configurations (dev, prod, etc.) with webpackConfig but ignore ones without it', async () => { - addProjectConfiguration(tree, 'myapp', { - root: 'apps/myapp', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/myapp/src/main.ts', - webpackConfig: 'apps/myapp/webpack.config.js', - }, - configurations: { - foo: {}, - bar: { - webpackConfig: 'apps/myapp/webpack.config.bar.js', - }, - }, - }, - }, - }); - tree.write('apps/myapp/webpack.config.js', 'default'); - tree.write('apps/myapp/webpack.config.bar.js', 'bar'); - - addProjectConfiguration(tree, 'alreadymigrated', { - root: 'apps/alreadymigrated', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - isolatedConfig: true, - main: 'apps/alreadymigrated/src/main.ts', - webpackConfig: 'apps/alreadymigrated/webpack.config.js', - }, - configurations: { - foo: {}, - bar: { - webpackConfig: 'apps/alreadymigrated/webpack.config.bar.js', - }, - }, - }, - }, - }); - tree.write('apps/alreadymigrated/webpack.config.js', 'default'); - tree.write('apps/alreadymigrated/webpack.config.bar.js', 'bar'); - - await webpackConfigSetup(tree); - - expect(tree.read('apps/myapp/webpack.config.old.js', 'utf-8')).toContain( - 'default' - ); - expect( - tree.read('apps/myapp/webpack.config.bar.old.js', 'utf-8') - ).toContain('bar'); - - expect( - tree.read('apps/alreadymigrated/webpack.config.js', 'utf-8') - ).toContain('default'); - expect( - tree.read('apps/alreadymigrated/webpack.config.bar.js', 'utf-8') - ).toContain('bar'); - expect( - tree.exists('apps/alreadymigrated/webpack.config.old.js') - ).toBeFalsy(); - expect( - tree.exists('apps/alreadymigrated/webpack.config.bar.old.js') - ).toBeFalsy(); - }); -}); diff --git a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts b/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts deleted file mode 100644 index 84e496f6d64c3..0000000000000 --- a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { - formatFiles, - logger, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { WebpackExecutorOptions } from '../../executors/webpack/schema'; -import { basename } from 'path'; - -export default async function (tree: Tree) { - // Since projects can have multiple configurations, we need to know if the default options - // need to be migrated or not. If so then the subsequent configurations with `webpackConfig` also need to be. - const defaultOptionsUpdated = new Set(); - forEachExecutorOptions( - tree, - '@nrwl/webpack:webpack', - ( - options: WebpackExecutorOptions, - projectName, - targetName, - configurationName - ) => { - const projectConfiguration = readProjectConfiguration(tree, projectName); - const defaultOptions = projectConfiguration.targets[targetName].options; - const defaultWasUpdated = defaultOptionsUpdated.has(projectName); - - // If default was not updated (for different configurations), we don't do anything - // If isolatedConfig is set, we don't need to do anything - // If project is React, we don't need to do anything - if ( - !defaultWasUpdated && - (defaultOptions?.isolatedConfig || - defaultOptions?.main?.match(/main\.(t|j)sx$/) || - defaultOptions?.webpackConfig === '@nrwl/react/plugins/webpack') - ) { - return; - } - defaultOptionsUpdated.add(projectName); - - // If this is not the base options (e.g. for development, production, or something custom), - // then skip it unless it specifically configures a webpackConfig file - if (configurationName && !options?.webpackConfig) { - return; - } - - // If webpackConfig is set, update it with the new options - // If webpackConfig is not set, we need to create a new - // webpack.config.js file and set the path to it in the - // executor options - - if (options?.webpackConfig) { - let oldName = options.webpackConfig; - if (options.webpackConfig.endsWith('.js')) { - oldName = options.webpackConfig.replace('.js', '.old.js'); - } - if (options.webpackConfig.endsWith('.ts')) { - oldName = options.webpackConfig.replace('.ts', '.old.ts'); - } - - renameFile(tree, options.webpackConfig, oldName); - const justTheFileName = basename(oldName); - - tree.write( - options.webpackConfig, - ` - const { composePlugins, withNx } = require('@nrwl/webpack'); - - // Nx plugins for webpack. - module.exports = composePlugins(withNx(), (config, { options, context }) => { - // Note: This was added by an Nx migration. - // You should consider inlining the logic into this file. - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return require('./${justTheFileName}')(config, context); - }); - ` - ); - - options.isolatedConfig = true; - - projectConfiguration.targets[targetName][ - configurationName ?? 'options' - ] = options; - updateProjectConfiguration(tree, projectName, projectConfiguration); - - logger.info( - ` - ${options.webpackConfig} has been renamed to ${oldName} and a new ${options.webpackConfig} - has been created for your project ${projectName}. - You should consider inlining the logic from ${oldName} into ${options.webpackConfig}. - You can read our guide on how to do this here: - - https://nx.dev/recipes/webpack/webpack-config-setup - ` - ); - } else { - const projectConfiguration = readProjectConfiguration( - tree, - projectName - ); - - if (!options) { - options = {} as WebpackExecutorOptions; - } - - options.webpackConfig = `${projectConfiguration.root}/webpack.config.js`; - options.isolatedConfig = true; - - tree.write( - options.webpackConfig, - ` - const { composePlugins, withNx } = require('@nrwl/webpack'); - - // Nx plugins for webpack. - module.exports = composePlugins(withNx(), (config) => { - // Update the webpack config as needed here. - // e.g. config.plugins.push(new MyPlugin()) - // For more information on webpack config and Nx see: - // https://nx.dev/recipes/webpack/webpack-config-setup - return config; - }); - ` - ); - - projectConfiguration.targets[targetName].options = options; - updateProjectConfiguration(tree, projectName, projectConfiguration); - } - } - ); - - await formatFiles(tree); -} - -function renameFile(tree: Tree, from: string, to: string) { - const buffer = tree.read(from); - if (!buffer) { - return; - } - tree.write(to, buffer); - tree.delete(from); -} diff --git a/packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.spec.ts b/packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.spec.ts deleted file mode 100644 index 7baad1244d942..0000000000000 --- a/packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { - addProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; -import addBabelUpwardRootModeFlag from './add-babelUpwardRootMode-flag'; - -describe('15.7.2 migration (add babelUpwardRootMode flag)', () => { - let tree: Tree; - - beforeEach(async () => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should add the babelUpwardRootMode flag to webpack projects', async () => { - addProjectConfiguration(tree, 'app1', { - root: 'apps/app1', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: {}, - }, - }, - }); - addProjectConfiguration(tree, 'app2', { - root: 'apps/app2', - targets: { - build: { - executor: '@nrwl/webpack:webpack', - options: { - babelUpwardRootMode: false, - }, - }, - }, - }); - - addProjectConfiguration(tree, 'app3', { - root: 'apps/app3', - targets: { - build: { - executor: '@nrwl/vite:build', - options: {}, - }, - }, - }); - await addBabelUpwardRootModeFlag(tree); - - const app1 = readProjectConfiguration(tree, 'app1'); - const app2 = readProjectConfiguration(tree, 'app2'); - const app3 = readProjectConfiguration(tree, 'app3'); - - expect(app1.targets['build'].options.babelUpwardRootMode).toBeTruthy(); - expect(app2.targets['build'].options.babelUpwardRootMode).toBeFalsy(); - expect(app3.targets['build'].options.babelUpwardRootMode).toBeUndefined(); - }); -}); diff --git a/packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.ts b/packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.ts deleted file mode 100644 index bfc3018244c5e..0000000000000 --- a/packages/webpack/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - formatFiles, - readProjectConfiguration, - Tree, - updateProjectConfiguration, -} from '@nx/devkit'; -import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils'; -import { WebpackExecutorOptions } from '../../executors/webpack/schema'; - -export default async function (tree: Tree) { - forEachExecutorOptions( - tree, - '@nrwl/webpack:webpack', - ( - options: WebpackExecutorOptions, - projectName, - targetName, - _configurationName - ) => { - if (options.babelUpwardRootMode !== undefined) { - return; - } - - const projectConfiguration = readProjectConfiguration(tree, projectName); - projectConfiguration.targets[targetName].options.babelUpwardRootMode = - true; - updateProjectConfiguration(tree, projectName, projectConfiguration); - } - ); - - await formatFiles(tree); -} diff --git a/packages/webpack/src/utils/module-federation/secondary-entry-points.ts b/packages/webpack/src/utils/module-federation/secondary-entry-points.ts index 9f22f09e185cd..272613df7e8e0 100644 --- a/packages/webpack/src/utils/module-federation/secondary-entry-points.ts +++ b/packages/webpack/src/utils/module-federation/secondary-entry-points.ts @@ -3,15 +3,7 @@ import { WorkspaceLibrarySecondaryEntryPoint } from './models'; import { dirname, join, relative } from 'path'; import { existsSync, lstatSync, readdirSync } from 'fs'; import { readJsonFile, joinPathFragments, workspaceRoot } from '@nx/devkit'; -import type { PackageJson } from 'nx/src/utils/package-json'; -import { requireNx } from '@nx/devkit/nx'; - -let { readModulePackageJson } = requireNx(); - -// TODO: Remove this in Nx 19 when Nx 16.7.0 is no longer supported -readModulePackageJson = - readModulePackageJson ?? - require('nx/src/utils/package-json').readModulePackageJson; +import { PackageJson, readModulePackageJson } from 'nx/src/utils/package-json'; export function collectWorkspaceLibrarySecondaryEntryPoints( library: WorkspaceLibrary, diff --git a/packages/workspace/migrations.json b/packages/workspace/migrations.json index 4e2e70c4d7092..cecaa5d0e77ba 100644 --- a/packages/workspace/migrations.json +++ b/packages/workspace/migrations.json @@ -1,11 +1,5 @@ { "generators": { - "15-7-0-split-configuration-into-project-json-files": { - "version": "15.7.0-beta.0", - "description": "Split global configuration files (e.g., workspace.json) into individual project.json files.", - "cli": "nx", - "implementation": "./src/migrations/update-15-7-0/split-configuration-into-project-json-files" - }, "update-16-0-0-add-nx-packages": { "cli": "nx", "version": "16.0.0-beta.1", @@ -26,18 +20,6 @@ } }, "packageJsonUpdates": { - "15.8.0": { - "version": "15.8.0-beta.2", - "x-prompt": "Do you want to update to TypeScript v4.9?", - "requires": { - "typescript": ">=4.8.2 <4.9.0" - }, - "packages": { - "typescript": { - "version": "~4.9.5" - } - } - }, "16.1.0": { "version": "16.1.0-beta.0", "x-prompt": "Do you want to update to TypeScript v5.0?", diff --git a/packages/workspace/src/generators/new/__snapshots__/generate-workspace-files.spec.ts.snap b/packages/workspace/src/generators/new/__snapshots__/generate-workspace-files.spec.ts.snap index b27f4cf97286e..59a2070b886e0 100644 --- a/packages/workspace/src/generators/new/__snapshots__/generate-workspace-files.spec.ts.snap +++ b/packages/workspace/src/generators/new/__snapshots__/generate-workspace-files.spec.ts.snap @@ -212,166 +212,6 @@ It will show tasks that you can run with Nx. " `; -exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for Core preset 1`] = ` -"# Proj - - - -✨ **This workspace has been generated by [Nx, Smart Monorepos · Fast CI.](https://nx.dev)** ✨ - -## Integrate with editors - -Enhance your Nx experience by installing [Nx Console](https://nx.dev/nx-console) for your favorite editor. Nx Console -provides an interactive UI to view your projects, run tasks, generate code, and more! Available for VSCode, IntelliJ and -comes with a LSP for Vim users. - -## Nx plugins and code generators - -Add Nx plugins to leverage their code generators and automated, inferred tasks. - -\`\`\` -# Add plugin -npx nx add @nx/react - -# Use code generator -npx nx generate @nx/react:app demo - -# Run development server -npx nx serve demo - -# View project details -npx nx show project demo --web -\`\`\` - -Run \`npx nx list\` to get a list of available plugins and whether they have generators. Then run \`npx nx list \` to see what generators are available. - -Learn more about [code generators](https://nx.dev/features/generate-code) and [inferred tasks](https://nx.dev/concepts/inferred-tasks) in the docs. - -## Running tasks - -To execute tasks with Nx use the following syntax: - -\`\`\` -npx nx <...options> -\`\`\` - -You can also run multiple targets: - -\`\`\` -npx nx run-many -t -\`\`\` - -..or add \`-p\` to filter specific projects - -\`\`\` -npx nx run-many -t -p -\`\`\` - -Targets can be defined in the \`package.json\` or \`projects.json\`. Learn more [in the docs](https://nx.dev/features/run-tasks). - -## Set up CI! - -Nx comes with local caching already built-in (check your \`nx.json\`). On CI you might want to go a step further. - -- [Set up remote caching](https://nx.dev/features/share-your-cache) -- [Set up task distribution across multiple machines](https://nx.dev/nx-cloud/features/distribute-task-execution) -- [Learn more how to setup CI](https://nx.dev/recipes/ci) - -## Explore the project graph - -Run \`npx nx graph\` to show the graph of the workspace. -It will show tasks that you can run with Nx. - -- [Learn more about Exploring the Project Graph](https://nx.dev/core-features/explore-graph) - -## Connect with us! - -- [Join the community](https://nx.dev/community) -- [Subscribe to the Nx Youtube Channel](https://www.youtube.com/@nxdevtools) -- [Follow us on Twitter](https://twitter.com/nxdevtools) -" -`; - -exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for Empty preset 1`] = ` -"# Proj - - - -✨ **This workspace has been generated by [Nx, Smart Monorepos · Fast CI.](https://nx.dev)** ✨ - -## Integrate with editors - -Enhance your Nx experience by installing [Nx Console](https://nx.dev/nx-console) for your favorite editor. Nx Console -provides an interactive UI to view your projects, run tasks, generate code, and more! Available for VSCode, IntelliJ and -comes with a LSP for Vim users. - -## Nx plugins and code generators - -Add Nx plugins to leverage their code generators and automated, inferred tasks. - -\`\`\` -# Add plugin -npx nx add @nx/react - -# Use code generator -npx nx generate @nx/react:app demo - -# Run development server -npx nx serve demo - -# View project details -npx nx show project demo --web -\`\`\` - -Run \`npx nx list\` to get a list of available plugins and whether they have generators. Then run \`npx nx list \` to see what generators are available. - -Learn more about [code generators](https://nx.dev/features/generate-code) and [inferred tasks](https://nx.dev/concepts/inferred-tasks) in the docs. - -## Running tasks - -To execute tasks with Nx use the following syntax: - -\`\`\` -npx nx <...options> -\`\`\` - -You can also run multiple targets: - -\`\`\` -npx nx run-many -t -\`\`\` - -..or add \`-p\` to filter specific projects - -\`\`\` -npx nx run-many -t -p -\`\`\` - -Targets can be defined in the \`package.json\` or \`projects.json\`. Learn more [in the docs](https://nx.dev/features/run-tasks). - -## Set up CI! - -Nx comes with local caching already built-in (check your \`nx.json\`). On CI you might want to go a step further. - -- [Set up remote caching](https://nx.dev/features/share-your-cache) -- [Set up task distribution across multiple machines](https://nx.dev/nx-cloud/features/distribute-task-execution) -- [Learn more how to setup CI](https://nx.dev/recipes/ci) - -## Explore the project graph - -Run \`npx nx graph\` to show the graph of the workspace. -It will show tasks that you can run with Nx. - -- [Learn more about Exploring the Project Graph](https://nx.dev/core-features/explore-graph) - -## Connect with us! - -- [Join the community](https://nx.dev/community) -- [Subscribe to the Nx Youtube Channel](https://www.youtube.com/@nxdevtools) -- [Follow us on Twitter](https://twitter.com/nxdevtools) -" -`; - exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for Expo preset 1`] = ` "# Proj diff --git a/packages/workspace/src/generators/utils/presets.ts b/packages/workspace/src/generators/utils/presets.ts index 4139c3d505957..06ea644fa84ae 100644 --- a/packages/workspace/src/generators/utils/presets.ts +++ b/packages/workspace/src/generators/utils/presets.ts @@ -1,12 +1,5 @@ export enum Preset { Apps = 'apps', - // TODO(v19): Remove Empty and Core presets - /** @deprecated Use Apps instead - */ - Empty = 'empty', - /** @deprecated Use NPM instead - */ - Core = 'core', NPM = 'npm', TS = 'ts', WebComponents = 'web-components', diff --git a/packages/workspace/src/migrations/update-15-7-0/split-configuration-into-project-json-files.ts b/packages/workspace/src/migrations/update-15-7-0/split-configuration-into-project-json-files.ts deleted file mode 100644 index 4f88365512a17..0000000000000 --- a/packages/workspace/src/migrations/update-15-7-0/split-configuration-into-project-json-files.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { formatFiles, Tree } from '@nx/devkit'; -import convertToNxProject from '../../generators/convert-to-nx-project/convert-to-nx-project'; - -export async function splitConfigurationIntoProjectJsonFiles(tree: Tree) { - await convertToNxProject(tree, { all: true }); - await formatFiles(tree); -} - -export default splitConfigurationIntoProjectJsonFiles;