From 69109e48d9c5e951c110ab16a9fb07ec95862e36 Mon Sep 17 00:00:00 2001 From: Shahar Kazaz Date: Wed, 2 Oct 2024 21:52:04 +0300 Subject: [PATCH 1/6] fix(js): resolve VerdaccioWarning on the "logs" configuration property (#28234) fix(js): resolve VerdaccioWarning: The configuration property "logs" has been deprecated; Replaced with "log" Currently, the Verdaccio configuration generated by running `nx generate setup-verdaccio` contains the deprecated `logs` property. I have updated this property to `log`, thereby removing the VerdaccioWarning that is displayed when running `nx local-registry` ## Current Behavior Currently, the Verdaccio configuration generated by running `nx generate setup-verdaccio` includes the deprecated 'logs' property. When you run `nx local-registry` Verdaccio displays the following warning: image ## Expected Behavior Run `nx local-registry` without the warning after using the `setup-verdaccio` generator. --- packages/js/src/generators/setup-verdaccio/files/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js/src/generators/setup-verdaccio/files/config.yml b/packages/js/src/generators/setup-verdaccio/files/config.yml index 1c97ff62b00ab..3dca5356ed3de 100644 --- a/packages/js/src/generators/setup-verdaccio/files/config.yml +++ b/packages/js/src/generators/setup-verdaccio/files/config.yml @@ -19,7 +19,7 @@ packages: proxy: npmjs # log settings -logs: +log: type: stdout format: pretty level: warn From 81892b51fd804705157e541cb652a9cb170c2f0e Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Wed, 2 Oct 2024 15:29:31 -0400 Subject: [PATCH 2/6] feat(misc)!: handle v20 deprecations in plugins (#28222) This PR removes these from v20 since they were deprecated and slated for removal: - `executeWebpackDevServerBuilder` export from `@nx/angular/executors`, users should use `executeDevServerBuilder` - `withStylus` util from `@nx/next/plugins/with-stylus` since it was deprecated in v17 and has just throw an error that users need to use SASS with Next.js The `getRollupOptions` function from `@nx/react/plugins/bundle-rollup` has been deprecated as mention previously and slated for removal in v22. New users are using inferred targets from Rollup, and existing projects using this module should run `nx g @nx/rollup:convert-to-inferred` or manually update rollup config to use `withNx` function. Also, bumped some deprecation for later in v21: - Remove inline builds from tsc/swc - Changes to SVGR to align with Webpack v5 (e.g. `import ReactComponent from './img.svg?svgr'`) - Remove `isolatedConfig` from Webpack executor -- requires a migration that extracts to a standard webpack config just in case (different from the original one that extracts to `withNx`) The ESLint TODOs were rescoped to `TODO(eslint)` and we'll look at it in further flat config work rather than tying it to an Nx release. ## Current Behavior ## Expected Behavior ## Related Issue(s) Fixes # --- docs/shared/mental-model/large-tasks.json | 5 ----- packages/angular/executors.ts | 11 +---------- packages/eslint-plugin/src/configs/javascript.ts | 4 ++-- packages/eslint-plugin/src/configs/typescript.ts | 4 ++-- .../eslint-plugin/src/flat-configs/javascript.ts | 4 ++-- .../eslint-plugin/src/flat-configs/typescript.ts | 4 ++-- packages/js/babel.ts | 2 +- packages/js/src/utils/schema.d.ts | 2 +- packages/js/src/utils/swc/compile-swc.ts | 2 +- packages/next/plugins/with-nx.ts | 2 +- packages/next/plugins/with-stylus.ts | 16 ---------------- packages/react/index.ts | 2 +- packages/react/plugins/bundle-rollup.ts | 5 ++++- .../react/plugins/component-testing/index.ts | 2 +- .../lib/apply-react-config.ts | 2 +- packages/webpack/index.ts | 2 +- .../webpack/src/executors/webpack/schema.d.ts | 2 +- 17 files changed, 22 insertions(+), 49 deletions(-) delete mode 100644 packages/next/plugins/with-stylus.ts diff --git a/docs/shared/mental-model/large-tasks.json b/docs/shared/mental-model/large-tasks.json index 036f0aec0a3e7..db86353145f03 100644 --- a/docs/shared/mental-model/large-tasks.json +++ b/docs/shared/mental-model/large-tasks.json @@ -18495,11 +18495,6 @@ "hash": "d750a6f13f1172e9c033370ead717b3f16d9f93b", "deps": ["npm:next", "devkit", "npm:@nrwl/next"] }, - { - "file": "packages/next/plugins/with-stylus.ts", - "hash": "f3a6bbd478d02c0e9940e4ebe3ab662456b53ebe", - "deps": ["npm:webpack-merge", "npm:next"] - }, { "file": "packages/next/project.json", "hash": "171f3c8158b2682525ffb65dac39edf04578460c" diff --git a/packages/angular/executors.ts b/packages/angular/executors.ts index 0d790947d3fee..9acb55309bf0c 100644 --- a/packages/angular/executors.ts +++ b/packages/angular/executors.ts @@ -9,13 +9,4 @@ export * from './src/executors/application/application.impl'; export * from './src/executors/extract-i18n/extract-i18n.impl'; export * from './src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl'; -import { executeDevServerBuilder } from './src/builders/dev-server/dev-server.impl'; - -export { - // TODO(v20): remove this alias - /** - * @deprecated Use executeDevServerBuilder instead. It will be removed in Nx v20. - */ - executeDevServerBuilder as executeWebpackDevServerBuilder, - executeDevServerBuilder, -}; +export { executeDevServerBuilder } from './src/builders/dev-server/dev-server.impl'; diff --git a/packages/eslint-plugin/src/configs/javascript.ts b/packages/eslint-plugin/src/configs/javascript.ts index 3e27e3cbd15da..d7ee56a602bc4 100644 --- a/packages/eslint-plugin/src/configs/javascript.ts +++ b/packages/eslint-plugin/src/configs/javascript.ts @@ -55,7 +55,7 @@ export default { * previously defined v5 of `@typescript-eslint`. v6 of `@typescript-eslint` * changed how configurations are defined. * - * TODO(v20): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx + * TODO(eslint): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx */ '@typescript-eslint/no-non-null-assertion': 'warn', '@typescript-eslint/adjacent-overload-signatures': 'error', @@ -70,7 +70,7 @@ export default { * During the migration to use ESLint v9 and typescript-eslint v8 for new workspaces, * this rule would have created a lot of noise, so we are disabling it by default for now. * - * TODO(v20): we should make this part of what we re-evaluate in v20 + * TODO(eslint): we should make this part of what we re-evaluate in v20 */ '@typescript-eslint/no-require-imports': 'off', }, diff --git a/packages/eslint-plugin/src/configs/typescript.ts b/packages/eslint-plugin/src/configs/typescript.ts index 62beee6919471..d3b812dc2319a 100644 --- a/packages/eslint-plugin/src/configs/typescript.ts +++ b/packages/eslint-plugin/src/configs/typescript.ts @@ -38,7 +38,7 @@ export default { * previously defined v5 of `@typescript-eslint`. v6 of `@typescript-eslint` * changed how configurations are defined. * - * TODO(v20): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx + * TODO(eslint): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx */ '@typescript-eslint/no-non-null-assertion': 'warn', '@typescript-eslint/adjacent-overload-signatures': 'error', @@ -53,7 +53,7 @@ export default { * During the migration to use ESLint v9 and typescript-eslint v8 for new workspaces, * this rule would have created a lot of noise, so we are disabling it by default for now. * - * TODO(v20): we should make this part of what we re-evaluate in v20 + * TODO(eslint): we should make this part of what we re-evaluate in v20 */ '@typescript-eslint/no-require-imports': 'off', }, diff --git a/packages/eslint-plugin/src/flat-configs/javascript.ts b/packages/eslint-plugin/src/flat-configs/javascript.ts index 95f9d69d1743e..e997c99500037 100644 --- a/packages/eslint-plugin/src/flat-configs/javascript.ts +++ b/packages/eslint-plugin/src/flat-configs/javascript.ts @@ -59,7 +59,7 @@ export default tseslint.config( * previously defined v5 of `@typescript-eslint`. v6 of `@typescript-eslint` * changed how configurations are defined. * - * TODO(v20): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx + * TODO(eslint): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx */ '@typescript-eslint/no-non-null-assertion': 'warn', '@typescript-eslint/adjacent-overload-signatures': 'error', @@ -74,7 +74,7 @@ export default tseslint.config( * During the migration to use ESLint v9 and typescript-eslint v8 for new workspaces, * this rule would have created a lot of noise, so we are disabling it by default for now. * - * TODO(v20): we should make this part of what we re-evaluate in v20 + * TODO(eslint): we should make this part of what we re-evaluate in v20 */ '@typescript-eslint/no-require-imports': 'off', }, diff --git a/packages/eslint-plugin/src/flat-configs/typescript.ts b/packages/eslint-plugin/src/flat-configs/typescript.ts index 6b04ba8b4cad5..c65e0020403ec 100644 --- a/packages/eslint-plugin/src/flat-configs/typescript.ts +++ b/packages/eslint-plugin/src/flat-configs/typescript.ts @@ -43,7 +43,7 @@ export default tseslint.config( * previously defined v5 of `@typescript-eslint`. v6 of `@typescript-eslint` * changed how configurations are defined. * - * TODO(v20): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx + * TODO(eslint): re-evalute these deviations from @typescript-eslint/recommended in v20 of Nx */ '@typescript-eslint/no-non-null-assertion': 'warn', '@typescript-eslint/adjacent-overload-signatures': 'error', @@ -58,7 +58,7 @@ export default tseslint.config( * During the migration to use ESLint v9 and typescript-eslint v8 for new workspaces, * this rule would have created a lot of noise, so we are disabling it by default for now. * - * TODO(v20): we should make this part of what we re-evaluate in v20 + * TODO(eslint): we should make this part of what we re-evaluate in v20 */ '@typescript-eslint/no-require-imports': 'off', }, diff --git a/packages/js/babel.ts b/packages/js/babel.ts index 5b7f944a8bb5c..d3eb3ac0924f1 100644 --- a/packages/js/babel.ts +++ b/packages/js/babel.ts @@ -37,7 +37,7 @@ module.exports = function (api: any, options: NxWebBabelPresetOptions = {}) { // Determine settings for `@babel//babel-plugin-transform-class-properties`, // so that we can sync the `loose` option with `@babel/preset-env`. - // TODO(v20): Remove classProperties since it's no longer needed, now that the class props transform is in preset-env. + // TODO(v21): Remove classProperties since it's no longer needed, now that the class props transform is in preset-env. const loose = options.classProperties?.loose ?? options.loose ?? true; if (options.classProperties) { logger.warn( diff --git a/packages/js/src/utils/schema.d.ts b/packages/js/src/utils/schema.d.ts index 22f77569cecc0..e4cc475ba574f 100644 --- a/packages/js/src/utils/schema.d.ts +++ b/packages/js/src/utils/schema.d.ts @@ -54,6 +54,6 @@ export interface NormalizedSwcExecutorOptions swcCliOptions: SwcCliOptions; tmpSwcrcPath: string; sourceRoot?: string; - // TODO(v20): remove inline feature + // TODO(v21): remove inline feature inline?: boolean; } diff --git a/packages/js/src/utils/swc/compile-swc.ts b/packages/js/src/utils/swc/compile-swc.ts index 9f48864ee8149..49b4936ee0ef5 100644 --- a/packages/js/src/utils/swc/compile-swc.ts +++ b/packages/js/src/utils/swc/compile-swc.ts @@ -21,7 +21,7 @@ function getSwcCmd( ) { const swcCLI = require.resolve('@swc/cli/bin/swc.js'); let inputDir: string; - // TODO(v20): remove inline feature + // TODO(v21): remove inline feature if (inline) { inputDir = originalProjectRoot.split('/')[0]; } else { diff --git a/packages/next/plugins/with-nx.ts b/packages/next/plugins/with-nx.ts index cb963ce444613..756190e5c2c1e 100644 --- a/packages/next/plugins/with-nx.ts +++ b/packages/next/plugins/with-nx.ts @@ -363,7 +363,7 @@ export function getNextConfig( const svgrOptions = typeof nx?.svgr === 'object' ? nx.svgr : defaultSvgrOptions; - // TODO(v20): Remove file-loader and use `?react` querystring to differentiate between asset and SVGR. + // TODO(v21): Remove file-loader and use `?react` querystring to differentiate between asset and SVGR. // It should be: // use: [{ // test: /\.svg$/i, diff --git a/packages/next/plugins/with-stylus.ts b/packages/next/plugins/with-stylus.ts deleted file mode 100644 index 5512f012acdd8..0000000000000 --- a/packages/next/plugins/with-stylus.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NextConfigFn } from '../src/utils/config'; -import { WithNxOptions } from './with-nx'; - -// TODO(v20): Remove file, it is here until users migrate over to SASS manually. -export function withStylus( - configOrFn: WithNxOptions | NextConfigFn -): NextConfigFn { - return async (phase: string) => { - throw new Error( - `Stylus support has been removed and you should use the built-in SASS support. Remove the "withStylus" plugin from your Next.js config, and rename your files from .styl to .scss.` - ); - }; -} - -module.exports = withStylus; -module.exports.withStylus = withStylus; diff --git a/packages/react/index.ts b/packages/react/index.ts index 23ca1dc851ef7..53e066ade4b63 100644 --- a/packages/react/index.ts +++ b/packages/react/index.ts @@ -1,6 +1,6 @@ import { NxReactWebpackPlugin as _NxReactWebpackPlugin } from './plugins/nx-react-webpack-plugin/nx-react-webpack-plugin'; -// TODO(v20): Remove this in favor of deep imports in order to load configs faster (150-200ms faster). +// TODO(v21): Remove this in favor of deep imports in order to load configs faster (150-200ms faster). /** @deprecated Use '@nx/react/webpack-plugin' instead. */ export const NxReactWebpackPlugin = _NxReactWebpackPlugin; diff --git a/packages/react/plugins/bundle-rollup.ts b/packages/react/plugins/bundle-rollup.ts index 0e3dfdd2a0954..eae13e6e8702b 100644 --- a/packages/react/plugins/bundle-rollup.ts +++ b/packages/react/plugins/bundle-rollup.ts @@ -1,6 +1,9 @@ import * as rollup from 'rollup'; -// TODO(v20): This should be deprecated and removed in v22. +// TODO(v22): Remove this in Nx 22 and migrate to explicit rollup.config.js files. +/** + * @deprecated Use `withNx` function from `@nx/rollup/with-nx` in your rollup.config.js file instead. Use `nx g @nx/rollup:convert-to-inferred` to generate the rollup.config.js file if it does not exist. + */ function getRollupOptions(options: rollup.RollupOptions) { const extraGlobals = { react: 'React', diff --git a/packages/react/plugins/component-testing/index.ts b/packages/react/plugins/component-testing/index.ts index 2803579b4f428..10b64d1e1f1a4 100644 --- a/packages/react/plugins/component-testing/index.ts +++ b/packages/react/plugins/component-testing/index.ts @@ -283,7 +283,7 @@ function buildTargetWebpack( return async () => { customWebpack = await customWebpack; - // TODO(v20): Component testing need to be agnostic of the underlying executor. With Crystal, we're not using `@nx/webpack:webpack` by default. + // TODO(v21): Component testing need to be agnostic of the underlying executor. With Crystal, we're not using `@nx/webpack:webpack` by default. // We need to decouple CT from the build target of the app, we just care about bundler config (e.g. webpack.config.js). // The generated setup should support both Webpack and Vite as documented here: https://docs.cypress.io/guides/component-testing/react/overview // Related issue: https://github.com/nrwl/nx/issues/21546 diff --git a/packages/react/plugins/nx-react-webpack-plugin/lib/apply-react-config.ts b/packages/react/plugins/nx-react-webpack-plugin/lib/apply-react-config.ts index 9e91309256900..6527ac60c83d8 100644 --- a/packages/react/plugins/nx-react-webpack-plugin/lib/apply-react-config.ts +++ b/packages/react/plugins/nx-react-webpack-plugin/lib/apply-react-config.ts @@ -21,7 +21,7 @@ export function applyReactConfig( const svgrOptions = typeof options.svgr === 'object' ? options.svgr : defaultSvgrOptions; - // TODO(v20): Remove file-loader and use `?react` querystring to differentiate between asset and SVGR. + // TODO(v21): Remove file-loader and use `?react` querystring to differentiate between asset and SVGR. // It should be: // use: [{ // test: /\.svg$/i, diff --git a/packages/webpack/index.ts b/packages/webpack/index.ts index 01590ba79ef74..e9ecb86b4dfb2 100644 --- a/packages/webpack/index.ts +++ b/packages/webpack/index.ts @@ -14,7 +14,7 @@ export { /** @deprecated Use `configurationGenerator` instead. */ export const webpackProjectGenerator = configurationGenerator; -// TODO(v20): Remove this in favor of deep imports in order to load configs faster (150-200ms faster). +// TODO(v21): Remove this in favor of deep imports in order to load configs faster (150-200ms faster). /** @deprecated Use NxAppWebpackPlugin from `@nx/webpack/app-plugin` instead. */ export const NxWebpackPlugin = NxAppWebpackPlugin; /** @deprecated Use NxTsconfigPathsWebpackPlugin from `@nx/webpack/tsconfig-paths-plugin` instead. */ diff --git a/packages/webpack/src/executors/webpack/schema.d.ts b/packages/webpack/src/executors/webpack/schema.d.ts index 29118edb08bc7..610e76f5c544e 100644 --- a/packages/webpack/src/executors/webpack/schema.d.ts +++ b/packages/webpack/src/executors/webpack/schema.d.ts @@ -47,7 +47,7 @@ export interface WebpackExecutorOptions { extractLicenses?: boolean; fileReplacements?: FileReplacement[]; generatePackageJson?: boolean; - // TODO(v20): Remove this option + // TODO(v21): Remove this option /** @deprecated set webpackConfig and provide an explicit webpack.config.js file (See: https://nx.dev/recipes/webpack/webpack-config-setup) */ isolatedConfig?: boolean; standardWebpackConfigFunction?: boolean; From 23a217d8dddffa115fea47e65b039268649af6ad Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Wed, 2 Oct 2024 20:33:10 -0400 Subject: [PATCH 3/6] feat(core): deprecate custom task runners (#28253) ## Current Behavior Custom task runners are a high level abstraction to customize caching, a relatively low level mechanism, to utilize other methods of remote caching. The abstraction of custom task runners makes it hard for Nx to make guarantees to make it faster. ## Expected Behavior Custom task runners are now deprecated. They will still work for Nx 20 but a warning will be shown when they are being used. The migration path is to use Nx Cloud (the ideal caching solution) or a Nx Powerpack cache (written by the Nx Core team which we can make guarantees about). ## Related Issue(s) Fixes # --- docs/generated/devkit/NxJsonConfiguration.md | 5 ++++- docs/generated/devkit/Workspace.md | 5 ++++- packages/nx/src/config/nx-json.ts | 3 ++- packages/nx/src/tasks-runner/run-command.ts | 21 ++++++++++++++++++-- packages/nx/src/utils/command-line-utils.ts | 3 +++ 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/docs/generated/devkit/NxJsonConfiguration.md b/docs/generated/devkit/NxJsonConfiguration.md index 93d50df8a539f..c7efdc6cdbd91 100644 --- a/docs/generated/devkit/NxJsonConfiguration.md +++ b/docs/generated/devkit/NxJsonConfiguration.md @@ -270,7 +270,10 @@ Dependencies between different target names across all projects • `Optional` **tasksRunnerOptions**: `Object` -Available Task Runners +**`Deprecated`** + +Custom task runners will no longer be supported in Nx 21. Use Nx Cloud or Nx Powerpack instead. +Available Task Runners for Nx to use #### Index signature diff --git a/docs/generated/devkit/Workspace.md b/docs/generated/devkit/Workspace.md index 1778f5ba0af7d..78fbb58467305 100644 --- a/docs/generated/devkit/Workspace.md +++ b/docs/generated/devkit/Workspace.md @@ -370,7 +370,10 @@ Dependencies between different target names across all projects • `Optional` **tasksRunnerOptions**: `Object` -Available Task Runners +**`Deprecated`** + +Custom task runners will no longer be supported in Nx 21. Use Nx Cloud or Nx Powerpack instead. +Available Task Runners for Nx to use #### Index signature diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index 4848d417d817d..65f789572e74c 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -393,7 +393,8 @@ export interface NxJsonConfiguration { appsDir?: string; }; /** - * Available Task Runners + * @deprecated Custom task runners will no longer be supported in Nx 21. Use Nx Cloud or Nx Powerpack instead. + * Available Task Runners for Nx to use */ tasksRunnerOptions?: { [tasksRunnerName: string]: { diff --git a/packages/nx/src/tasks-runner/run-command.ts b/packages/nx/src/tasks-runner/run-command.ts index a94c275afe850..019b307c10a2c 100644 --- a/packages/nx/src/tasks-runner/run-command.ts +++ b/packages/nx/src/tasks-runner/run-command.ts @@ -790,7 +790,7 @@ export function getRunner( runnerOptions: any; } { let runner = nxArgs.runner; - runner = runner || 'default'; + runner = runner ?? 'default'; if (runner !== 'default' && !nxJson.tasksRunnerOptions?.[runner]) { throw new Error(`Could not find runner configuration for ${runner}`); @@ -799,6 +799,16 @@ export function getRunner( const modulePath: string = getTasksRunnerPath(runner, nxJson); try { + if (isCustomRunnerPath(modulePath)) { + output.warn({ + title: `Custom task runners will no longer be supported in Nx 21.`, + bodyLines: [ + `Use Nx Cloud or the Nx Powerpack caches instead.`, + `For more information, see https://nx.dev/features/powerpack/custom-caching`, + ], + }); + } + const tasksRunner = loadTasksRunner(modulePath); return { @@ -815,6 +825,8 @@ export function getRunner( } } +const defaultTasksRunnerPath = require.resolve('./default-tasks-runner'); + function getTasksRunnerPath( runner: string, nxJson: NxJsonConfiguration @@ -838,7 +850,7 @@ function getTasksRunnerPath( // Nx Cloud ID specified in nxJson nxJson.nxCloudId; - return isCloudRunner ? 'nx-cloud' : require.resolve('./default-tasks-runner'); + return isCloudRunner ? 'nx-cloud' : defaultTasksRunnerPath; } export function getRunnerOptions( @@ -901,3 +913,8 @@ export function getRunnerOptions( return result; } +function isCustomRunnerPath(modulePath: string) { + return !['nx-cloud', '@nrwl/nx-cloud', defaultTasksRunnerPath].includes( + modulePath + ); +} diff --git a/packages/nx/src/utils/command-line-utils.ts b/packages/nx/src/utils/command-line-utils.ts index 4689468824867..19a83feb79849 100644 --- a/packages/nx/src/utils/command-line-utils.ts +++ b/packages/nx/src/utils/command-line-utils.ts @@ -14,6 +14,9 @@ export interface RawNxArgs extends NxArgs { export interface NxArgs { targets?: string[]; configuration?: string; + /** + * @deprecated Custom task runners will no longer be supported in Nx 21. Use Nx Cloud or Nx Powerpack instead. + */ runner?: string; parallel?: number; untracked?: boolean; From 8c59a7eb40ef41808029a6676a142d44bd147796 Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Wed, 2 Oct 2024 20:45:10 -0400 Subject: [PATCH 4/6] fix(core): filter out task dependencies on itself (#28261) ## Current Behavior Tasks can end up depending on themselves if they depend on a dummy task which ends up depending back on itself. This throws a weird error like: ``` NX Could not execute command because the task graph has a circular dependency devkit:build --> devkit:build-base --> nx:build-base --> nx:build-base ``` ## Expected Behavior Tasks cannot depend on themselves. No errors are thrown in those cases. ## Related Issue(s) Fixes # --- .../tasks-runner/create-task-graph.spec.ts | 65 +++++++++++++++++++ .../nx/src/tasks-runner/create-task-graph.ts | 10 +-- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/packages/nx/src/tasks-runner/create-task-graph.spec.ts b/packages/nx/src/tasks-runner/create-task-graph.spec.ts index 76b9e71425938..9e5a6fc195e35 100644 --- a/packages/nx/src/tasks-runner/create-task-graph.spec.ts +++ b/packages/nx/src/tasks-runner/create-task-graph.spec.ts @@ -1490,6 +1490,71 @@ describe('createTaskGraph', () => { }); }); + it('should handle cycles where tasks seem to depend on themselves (lib1:build -> lib2 -> lib1:build)', () => { + projectGraph = { + nodes: { + lib1: { + name: 'lib1', + type: 'lib', + data: { + root: 'lib1-root', + targets: { + build: { + executor: 'nx:run-commands', + }, + }, + }, + }, + lib2: { + name: 'lib2', + type: 'lib', + data: { + root: 'lib2-root', + targets: {}, + }, + }, + }, + dependencies: { + lib1: [{ source: 'lib1', target: 'lib2', type: 'static' }], + lib2: [{ source: 'lib2', target: 'lib1', type: 'static' }], + }, + }; + + const taskGraph = createTaskGraph( + projectGraph, + { + build: [{ target: 'build', dependencies: true }], + }, + ['lib1'], + ['build'], + 'development', + { + __overrides_unparsed__: [], + } + ); + expect(taskGraph).toEqual({ + roots: ['lib1:build'], + tasks: { + 'lib1:build': expect.objectContaining({ + id: 'lib1:build', + target: { + project: 'lib1', + target: 'build', + }, + outputs: expect.arrayContaining([expect.any(String)]), + overrides: { + __overrides_unparsed__: [], + }, + projectRoot: 'lib1-root', + parallelism: true, + }), + }, + dependencies: { + 'lib1:build': [], + }, + }); + }); + it('should handle cycles between projects where all projects do not contain the same task target (lib1:build -> lib2:build -> lib3 -> lib4:build -> lib1:build)', () => { projectGraph = { nodes: { diff --git a/packages/nx/src/tasks-runner/create-task-graph.ts b/packages/nx/src/tasks-runner/create-task-graph.ts index 5c128af4e4980..62d3b695e12ad 100644 --- a/packages/nx/src/tasks-runner/create-task-graph.ts +++ b/packages/nx/src/tasks-runner/create-task-graph.ts @@ -85,10 +85,12 @@ export class ProcessTasks { this.filterDummyTasks(); - for (const projectName of Object.keys(this.dependencies)) { - if (this.dependencies[projectName].length > 1) { - this.dependencies[projectName] = [ - ...new Set(this.dependencies[projectName]).values(), + for (const taskId of Object.keys(this.dependencies)) { + if (this.dependencies[taskId].length > 0) { + this.dependencies[taskId] = [ + ...new Set( + this.dependencies[taskId].filter((d) => d !== taskId) + ).values(), ]; } } From 84a5c7a2747c01dc8813aab33740da195c0b449f Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Wed, 2 Oct 2024 21:55:36 -0400 Subject: [PATCH 5/6] chore(core): expose utility to determine if db cache is enabled (#28262) ## Current Behavior There is no function to determine if the db cache is enabled ## Expected Behavior There is a function to determine if the db cache is enabled. ## Related Issue(s) Fixes # --- packages/nx/src/tasks-runner/cache.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/nx/src/tasks-runner/cache.ts b/packages/nx/src/tasks-runner/cache.ts index 33882bcb210d9..55447db4bbea3 100644 --- a/packages/nx/src/tasks-runner/cache.ts +++ b/packages/nx/src/tasks-runner/cache.ts @@ -29,11 +29,17 @@ export type CachedResult = { }; export type TaskWithCachedResult = { task: Task; cachedResult: CachedResult }; +export function dbCacheEnabled(nxJson: NxJsonConfiguration = readNxJson()) { + return ( + process.env.NX_DISABLE_DB !== 'true' && + (nxJson.enableDbCache === true || process.env.NX_DB_CACHE === 'true') + ); +} + // Do not change the order of these arguments as this function is used by nx cloud export function getCache(options: DefaultTasksRunnerOptions): DbCache | Cache { const nxJson = readNxJson(); - return process.env.NX_DISABLE_DB !== 'true' && - (nxJson.enableDbCache === true || process.env.NX_DB_CACHE === 'true') + return dbCacheEnabled(nxJson) ? new DbCache({ // Remove this in Nx 21 nxCloudRemoteCache: isNxCloudUsed(nxJson) ? options.remoteCache : null, From c655b6cf4f8c65a03edde1ff3c79a7ba093b5c48 Mon Sep 17 00:00:00 2001 From: Benjamin Cabanes <3447705+bcabanes@users.noreply.github.com> Date: Thu, 3 Oct 2024 03:09:03 -0400 Subject: [PATCH 6/6] feat(nx-dev): add nx powerpack gcp & azure mentions (#28256) Co-authored-by: Juri --- .../ui-animations/src/lib/animated-beam.tsx | 18 +- nx-dev/ui-icons/src/index.ts | 1 + .../src/lib/ci-providers/google-cloud.tsx | 14 + .../src/lib/powerpack-features.tsx | 289 ++++++++++++++---- 4 files changed, 244 insertions(+), 78 deletions(-) create mode 100644 nx-dev/ui-icons/src/lib/ci-providers/google-cloud.tsx diff --git a/nx-dev/ui-animations/src/lib/animated-beam.tsx b/nx-dev/ui-animations/src/lib/animated-beam.tsx index e4ee814875d53..cf7d768b4f97c 100644 --- a/nx-dev/ui-animations/src/lib/animated-beam.tsx +++ b/nx-dev/ui-animations/src/lib/animated-beam.tsx @@ -188,20 +188,16 @@ export const AnimatedCurvedBeam: FC = ({ animate={animateValue} transition={{ delay, - duration, + duration: bidirectional ? duration * 2 : duration, ease: [0.16, 1, 0.3, 1], // https://easings.net/#easeOutExpo repeat: Infinity, repeatDelay: 0, }} > - - - - + + + + @@ -361,8 +357,8 @@ export const AnimatedAngledBeam: FC = ({ - - + + diff --git a/nx-dev/ui-icons/src/index.ts b/nx-dev/ui-icons/src/index.ts index c626dcfe9ae04..d78f56e0ec3cf 100644 --- a/nx-dev/ui-icons/src/index.ts +++ b/nx-dev/ui-icons/src/index.ts @@ -3,6 +3,7 @@ export * from './lib/ci-providers/azure-devops'; export * from './lib/ci-providers/bitbucket'; export * from './lib/ci-providers/github'; export * from './lib/ci-providers/gitlab'; +export * from './lib/ci-providers/google-cloud'; export * from './lib/ci-providers/jenkins'; export * from './lib/ci-providers/travis-ci'; diff --git a/nx-dev/ui-icons/src/lib/ci-providers/google-cloud.tsx b/nx-dev/ui-icons/src/lib/ci-providers/google-cloud.tsx new file mode 100644 index 0000000000000..150175e707202 --- /dev/null +++ b/nx-dev/ui-icons/src/lib/ci-providers/google-cloud.tsx @@ -0,0 +1,14 @@ +import { FC, SVGProps } from 'react'; + +export const GoogleCloudIcon: FC> = (props) => ( + + Google Cloud + + +); diff --git a/nx-dev/ui-powerpack/src/lib/powerpack-features.tsx b/nx-dev/ui-powerpack/src/lib/powerpack-features.tsx index 9d4b3dec306c4..ac06a0dd91c8b 100644 --- a/nx-dev/ui-powerpack/src/lib/powerpack-features.tsx +++ b/nx-dev/ui-powerpack/src/lib/powerpack-features.tsx @@ -1,14 +1,20 @@ 'use client'; -import { forwardRef, ReactElement, ReactNode, useRef } from 'react'; +import { + forwardRef, + ReactElement, + ReactNode, + useCallback, + useEffect, + useRef, + useState, +} from 'react'; import { ButtonLink, SectionHeading, Strong } from '@nx/nx-dev/ui-common'; import { cx } from '@nx/nx-dev/ui-primitives'; -import { AnimatedAngledBeam } from '@nx/nx-dev/ui-animations'; -import { - CalendarDaysIcon, - CircleStackIcon, - ServerIcon, -} from '@heroicons/react/24/outline'; -import { NxIcon } from '@nx/nx-dev/ui-icons'; +import { AnimatedCurvedBeam } from '@nx/nx-dev/ui-animations'; +import { CircleStackIcon, ServerIcon } from '@heroicons/react/24/outline'; +import { AzureDevOpsIcon, GoogleCloudIcon, NxIcon } from '@nx/nx-dev/ui-icons'; +import Link from 'next/link'; +import { AnimatePresence, motion } from 'framer-motion'; export function PowerpackFeatures(): ReactElement { return ( @@ -146,15 +152,22 @@ export function PowerpackFeatures(): ReactElement { const Card = forwardRef< HTMLDivElement, - { className?: string; children?: ReactNode } ->(({ className, children }, ref) => { + { + className?: string; + children?: ReactNode; + onMouseEnter?: () => void; + onMouseLeave?: () => void; + } +>(({ className, children, onMouseEnter, onMouseLeave }, ref) => { return (
{children}
@@ -164,99 +177,241 @@ const Card = forwardRef< Card.displayName = 'Card'; export function CustomRemoteCacheAnimation(): ReactElement { + const awsRef = useRef(null); + const azureRef = useRef(null); const containerRef = useRef(null); - const gitHubRef = useRef(null); - const gitlabRef = useRef(null); + const gcpRef = useRef(null); + const networkDriveRef = useRef(null); const nxRef = useRef(null); - const computerRef = useRef(null); + + const animatedBeamMap: Record = { + aws: ( + + ), + azure: ( + + ), + gcp: ( + + ), + networkDrive: ( + + ), + }; + + const links = Object.keys(animatedBeamMap); + const duration = 6000; + const timeout = useRef(); + const [selected, setSelected] = useState('aws'); + const [autoplay, setAutoplay] = useState(true); + + const play = useCallback(() => { + timeout.current = setTimeout(next, duration); + }, [selected]); + + const next = () => { + if (links.length <= 1) return; // No change if there's only one or no items + + if (selected === null) + return setSelected(links[Math.floor(Math.random() * links.length)]); + + const availableLinks = links.filter((link) => link !== selected); + const randomIndex = Math.floor(Math.random() * availableLinks.length); + setSelected(availableLinks[randomIndex]); + }; + + useEffect(() => { + clearTimeout(timeout.current); + if (autoplay) play(); + }, [selected, autoplay, play]); return (
- +
-
- -
+
+ { + setAutoplay(false); + setSelected('aws'); + }} + onMouseLeave={() => { + setAutoplay(true); + setSelected(null); + }} + className={cx( + 'relative transition hover:bg-slate-50 dark:hover:bg-slate-800', + { 'bg-slate-50 dark:bg-slate-800': selected === 'aws' } + )} + > +
AWS
-
S3
+
S3
- + Get started - +
- -
+ { + setAutoplay(false); + setSelected('networkDrive'); + }} + onMouseLeave={() => { + setAutoplay(true); + setSelected(null); + }} + className={cx( + 'relative transition hover:bg-slate-50 dark:hover:bg-slate-800', + { 'bg-slate-50 dark:bg-slate-800': selected === 'networkDrive' } + )} + > +
Network drive
-
- -
- More soon! + { + setAutoplay(false); + setSelected('gcp'); + }} + onMouseLeave={() => { + setAutoplay(true); + setSelected(null); + }} + className={cx( + 'relative transition hover:bg-slate-50 dark:hover:bg-slate-800', + { 'bg-slate-50 dark:bg-slate-800': selected === 'gcp' } + )} + > +
+ GCP
-
- - - + + {selected ? ( + + {animatedBeamMap[selected]} + + ) : null} +
); }