nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.39k stars 2.33k forks source link

fix: 🐛 migrating to 18.0.x gives error: Cannot find configuration for task workspace:serve #21698

Closed bjornharvold closed 5 months ago

bjornharvold commented 8 months ago

Current Behavior

After upgrading to 18.x, we are no longer able to serve our SPAs. Instead, it errors out.

The project.json looks like this:

{
  "name": "extranet",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/extranet/src",
  "prefix": "wink",
  "targets": {
    "build": {
      "executor": "@angular-devkit/build-angular:application",
      "outputs": ["{options.outputPath}"],
      "options": {
        "allowedCommonJsDependencies": [
          "hammerjs",
          "clone-deep",
          "lodash.clonedeep",
          "lodash.debounce",
          "flat",
          "fast-sha256",
          "rfdc"
        ],
        "baseHref": "/",
        "outputPath": "dist/apps/extranet",
        "index": "apps/extranet/src/index.html",
        "browser": "apps/extranet/src/main.ts",
        "polyfills": ["zone.js"],
        "tsConfig": "apps/extranet/tsconfig.app.json",
        "stylePreprocessorOptions": {
          "includePaths": ["shared-styles/common", "shared-styles/extranet"]
        },
        "assets": [
          "apps/extranet/src/assets",
          "apps/extranet/src/manifest.json",
          "apps/extranet/src/robots.txt"
        ],
        "styles": [
          "node_modules/ng-sortgrid/styles/ngsg.css",
          "node_modules/npm-font-open-sans/open-sans.css",
          "apps/extranet/src/assets/styles/traveliko.css",
          "shared-styles/extranet/theme/default/styles.scss"
        ],
        "scripts": []
      },
      "configurations": {
        "production": {
          "fileReplacements": [
            {
              "replace": "apps/extranet/src/environments/environment.ts",
              "with": "apps/extranet/src/environments/environment.prod.ts"
            }
          ],
          "baseHref": "/",
          "optimization": {
            "scripts": true,
            "styles": {
              "minify": true,
              "inlineCritical": true
            },
            "fonts": true
          },
          "outputHashing": "all",
          "sourceMap": {
            "scripts": true,
            "hidden": true
          },
          "namedChunks": false,
          "extractLicenses": true,
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "3mb",
              "maximumError": "5mb"
            },
            {
              "type": "anyComponentStyle",
              "maximumWarning": "25kb",
              "maximumError": "30kb"
            }
          ],
          "serviceWorker": "apps/extranet/ngsw-config.json"
        },
        "staging": {
          "fileReplacements": [
            {
              "replace": "apps/extranet/src/environments/environment.ts",
              "with": "apps/extranet/src/environments/environment.staging.ts"
            }
          ],
          "baseHref": "/",
          "optimization": {
            "scripts": true,
            "styles": {
              "minify": true,
              "inlineCritical": true
            },
            "fonts": true
          },
          "outputHashing": "all",
          "sourceMap": {
            "scripts": true,
            "hidden": true
          },
          "namedChunks": false,
          "extractLicenses": true,
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "3mb",
              "maximumError": "5mb"
            },
            {
              "type": "anyComponentStyle",
              "maximumWarning": "25kb",
              "maximumError": "30kb"
            }
          ],
          "serviceWorker": "apps/extranet/ngsw-config.json"
        },
        "development": {
          "optimization": false,
          "extractLicenses": false,
          "sourceMap": true,
          "namedChunks": true
        }
      },
      "defaultConfiguration": "production"
    },
    "serve": {
      "executor": "@angular-devkit/build-angular:dev-server",
      "configurations": {
        "development": {
          "buildTarget": "extranet:build:development"
        },
        "production": {
          "buildTarget": "extranet:build:production"
        }
      }
    },
    "extract-i18n": {
      "executor": "@angular-devkit/build-angular:extract-i18n",
      "options": {
        "buildTarget": "extranet:build"
      }
    },
    "lint": {
      "executor": "@nx/eslint:lint",
      "outputs": ["{options.outputFile}"]
    },
    "test": {
      "executor": "@nx/jest:jest",
      "outputs": ["{workspaceRoot}/coverage/apps/extranet"],
      "options": {
        "jestConfig": "apps/extranet/jest.config.ts"
      }
    }
  },
  "tags": ["domain:extranet", "type:app"],
  "implicitDependencies": []
}

Expected Behavior

On v17.x, our apps serve up SPAs without any issues.

GitHub Repo

No response

Steps to Reproduce

  1. Upgrade from 17 -> 18 with npx nx migrate latest
  2. Start the app: node --max_old_space_size=16384 ./node_modules/.bin/nx serve --host=dev.wink.travel --port=8001 --project=extranet --ssl=true --ssl-key=./certs/dev.wink.travel-key.pem --ssl-cert=./certs/dev.wink.travel.pem --parallel --configuration=development

Nx Report

Node   : 20.11.0
   OS     : darwin-arm64
   yarn   : 1.22.21

   nx (global)        : 17.1.3
   nx                 : 18.0.3
   @nx/js             : 18.0.3
   @nx/jest           : 18.0.3
   @nx/linter         : 18.0.3
   @nx/eslint         : 18.0.3
   @nx/workspace      : 18.0.3
   @nx/angular        : 18.0.3
   @nx/cypress        : 18.0.3
   @nx/devkit         : 18.0.3
   @nx/eslint-plugin  : 18.0.3
   @nx/storybook      : 18.0.3
   @nrwl/tao          : 18.0.3
   @nx/web            : 18.0.3
   @nx/webpack        : 18.0.3
   typescript         : 5.3.3
   ---------------------------------------
   Community plugins:
   @compodoc/compodoc               : 1.1.23
   @fortawesome/angular-fontawesome : 0.14.1
   @jscutlery/semver                : 4.2.0
   @ng-bootstrap/ng-bootstrap       : 16.0.0
   @ngneat/transloco                : 6.0.4
   @ngrx/component                  : 17.1.0
   @ngrx/component-store            : 17.1.0
   @ngrx/data                       : 17.1.0
   @ngrx/effects                    : 17.1.0
   @ngrx/entity                     : 17.1.0
   @ngrx/router-store               : 17.1.0
   @ngrx/schematics                 : 17.1.0
   @ngrx/store                      : 17.1.0
   @ngrx/store-devtools             : 17.1.0
   @storybook/angular               : 7.6.13
   angular-calendar                 : 0.31.0

Failure Logs

>  NX   Cannot find configuration for task workspace:serve

Package Manager Version

Yarn 1.22.21

Operating System

Additional Information

No response

beeman commented 7 months ago

I also see this with new Next.js apps.

For convenience, the steps to reproduce are in this Dockerfile:

FROM node:20-alpine

WORKDIR /root

RUN apk add --update --no-cache git python3 make g++

RUN corepack enable
RUN corepack prepare pnpm@8 --activate

RUN pnpx create-nx-workspace@latest web \
    --preset next \
        --appName web \
    --style css \
    --workspaceType integrated \
    --nextAppDir \
    --nextSrcDir \
     --e2eTestRunner none \
    --nxCloud skip

WORKDIR /root/web

ENTRYPOINT /bin/sh

To run this:

# Build the container
$ docker build . -t nx-18-next
# Run the container
$ docker run -it nx-18-next

You are now inside the container and should be able to start the Next project:

~/web # pnpm nx serve web

 >  NX   Cannot find configuration for task web:serve

   Pass --verbose to see the stacktrace.

The nx report from inside this container:

~/web # pnpm nx report

 >  NX   Report complete - copy this into the issue template

   Node   : 20.11.0
   OS     : linux-x64
   pnpm   : 8.15.2

   nx                 : 18.0.4
   @nx/js             : 18.0.4
   @nx/jest           : 18.0.4
   @nx/linter         : 18.0.4
   @nx/eslint         : 18.0.4
   @nx/workspace      : 18.0.4
   @nx/devkit         : 18.0.4
   @nx/eslint-plugin  : 18.0.4
   @nx/next           : 18.0.4
   @nx/react          : 18.0.4
   @nrwl/tao          : 18.0.4
   @nx/web            : 18.0.4
   @nx/webpack        : 18.0.4
   typescript         : 5.3.3

Running the above with create-nx-workspace@17 makes it work as expected.

leosvelperez commented 7 months ago

@bjornharvold thanks for reporting this!

Could you please post the project configuration for the workspace project? You provided the project configuration for the extranet project, but the failure logs reference the workspace:serve target which is not from that project.

Also, could you tell me if you have a plugins entry in your nx.json? If you do, could you share it?


@beeman thanks for the detailed reproduction!

In your case, the serve target is not available for the project. Instead, you have the dev and start targets. Those are the commands the Next.js CLI provides to run your applications and the new inferred targets for Next.js reflect that. You can see the available targets by running pnpm nx show project web --web. Note the new targets are explained in our docs: https://nx.dev/nx-api/next#using-nextjs. Also, you can customize the targets if you prefer to stick with serve for one of them by configuring the plugin in nx.json accordingly:

{
  ...
  "plugins": [
    {
      "plugin": "@nx/next/plugin",
      "options": {
        "buildTargetName": "build",
-       "devTargetName": "dev",
+       "devTargetName": "serve",
        "startTargetName": "start"
        "startTargetName": "serve"
      }
    },
    ...
  ]
}
beeman commented 7 months ago

@beeman thanks for the detailed reproduction!

In your case, the serve target is not available for the project. Instead, you have the dev and start targets. Those are the commands the Next.js CLI provides to run your applications and the new inferred targets for Next.js reflect that.

Thanks, @leosvelperez, running pnpm nx dev web works.

However, for me this is a breaking change between v17 and v18 with no deprecation, I would expect the serve command to still work and warn me that it's being deprecated and removed in the next major. That would have easily saved me (and my mentee) like 3 or 4 hours yesterday.

You can see the available targets by running pnpm nx show project web --web.

I think having to do this is a huge step down from opening a file and checking what's there. In addition, this doesn't "just work" when running it inside a container or remote host, and running this command without the --web flag leaves an unreadable blob of JSON, which would require additional tooling to read it.

On the other hand, a file can just be opened and looked at, regardless where you have it 💡

image

But I understand both of my comments are out of the scope of this issue so I'll pick them up elsewhere.

bjornharvold commented 7 months ago

Greetings @leosvelperez

We have no "workspace" project. Here's my nx.json:

{
  "affected": {
    "defaultBase": "master"
  },
  "tasksRunnerOptions": {
    "default": {
      "runner": "@nx/workspace/tasks-runners/default",
      "options": {}
    }
  },
  "cli": {
    "packageManager": "yarn"
  },
  "defaultProject": "booking-engine",
  "generators": {
    "@nx/angular:application": {
      "style": "scss",
      "linter": "eslint",
      "unitTestRunner": "jest",
      "e2eTestRunner": "cypress",
      "standalone": true,
      "strict": true,
      "projectNameAndRootFormat": "as-provided"
    },
    "@nx/angular:library": {
      "linter": "eslint",
      "unitTestRunner": "jest",
      "style": "scss",
      "strict": true,
      "projectNameAndRootFormat": "as-provided"
    },
    "@nx/angular:component": {
      "style": "scss",
      "changeDetection": "OnPush",
      "standalone": true,
      "export": true,
      "nameAndDirectoryFormat": "as-provided"
    },
    "@nx/angular:pipe": {
      "standalone": true,
      "export": true,
      "nameAndDirectoryFormat": "as-provided"
    },
    "@nx/angular": {
      "application": {
        "linter": "eslint"
      },
      "library": {
        "linter": "eslint"
      },
      "storybook-configuration": {
        "linter": "eslint"
      }
    },
    "@nx/workspace:move": {
      "projectNameAndRootFormat": "as-provided"
    }
  },
  "$schema": "./node_modules/nx/schemas/nx-schema.json",
  "targetDefaults": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["production", "^production"],
      "cache": true
    },
    "build-storybook": {
      "inputs": [
        "default",
        "^production",
        "{projectRoot}/.storybook/**/*",
        "{projectRoot}/tsconfig.storybook.json"
      ],
      "cache": true
    },
    "lint": {
      "cache": true
    },
    "test": {
      "cache": true
    },
    "e2e": {
      "cache": true,
      "inputs": ["default", "^production"]
    },
    "@nx/jest:jest": {
      "cache": true,
      "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
      "options": {
        "passWithNoTests": true
      },
      "configurations": {
        "ci": {
          "ci": true,
          "codeCoverage": true
        }
      }
    },
    "@nx/eslint:lint": {
      "cache": true,
      "inputs": [
        "default",
        "{workspaceRoot}/.eslintrc.json",
        "{workspaceRoot}/tools/eslint-rules/**/*"
      ]
    }
  },
  "namedInputs": {
    "default": ["{projectRoot}/**/*", "sharedGlobals"],
    "sharedGlobals": ["{workspaceRoot}/workspace.json"],
    "production": [
      "default",
      "!{projectRoot}/.storybook/**/*",
      "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)",
      "!{projectRoot}/tsconfig.storybook.json",
      "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
      "!{projectRoot}/tsconfig.spec.json",
      "!{projectRoot}/jest.config.[jt]s",
      "!{projectRoot}/src/test-setup.[jt]s",
      "!{projectRoot}/.eslintrc.json"
    ]
  },
  "workspaceLayout": {}
}
leosvelperez commented 7 months ago

I see. Is workspace the name of the package.json at the root? If you open the project graph, can you see a workspace project? Can you run nx show project workspace and share the results here?

Also, just to confirm, is the error happening when serving a single project (e.g. extranet)?

bjornharvold commented 7 months ago

Here's the root project.json.

{
  "name": "workspace",
  "$schema": "node_modules/nx/schemas/project-schema.json",
  "targets": {
    "version": {
      "executor": "@jscutlery/semver:version",
      "options": {
        "syncVersions": true,
        "commitMessageFormat": "chore(${projectName}): publish version ${version}"
      }
    },
    "github": {
      "executor": "@jscutlery/semver:github",
      "options": {
        "target": "master",
        "tag": "${tag}",
        "notes": "${notes}"
      }
    }
  },
  "tags": []
}

What's in there is there to support the semver plugin by @edbzn. We upgraded to the new semver plugin at the same time and there was nothing in the release notes that said to remove this. Ed said an entire rewrite was required to remove this hack.

Is it an Nx issue or a jscutlery/semver issue?

leosvelperez commented 7 months ago

That makes workspace to be a project, but still, I don't understand why running nx serve extranet would try to serve workspace. That's why I was asking if you are facing this issue when serving a single app or if you're running a different command (e.g. run-many, affected) to serve apps.

bjornharvold commented 7 months ago

It failed when running serve on all our [actual] projects. Did not try other commands. Will do so today.

leosvelperez commented 7 months ago

No need to try other commands. I just wanted to confirm whether running nx serve extranet surfaces that error. Given your response, I imagine that's the case.

That's very strange. The error you're getting is only thrown when building the task graph to execute the command. Taking into account the project configuration you provided and your nx.json file, running the command you mentioned in this thread description should only create a task graph with a single node: extranet:serve:development. The serve target doesn't have any dependencies on other tasks (no dependsOn or entry in targetDefaults). It uses the build target, but that's an internal implementation detail of the @angular-devkit/build-angular:dev-server builder, so that task is not pulled into the task graph (and even if it was, it's still not workspace:serve).

I'll create a repo with the configuration as close as possible to the one you provided and see if I can reproduce it.

leosvelperez commented 7 months ago

@bjornharvold I tried to reproduce this using all the info you've provided so far and I couldn't. You can see the repo I ended up with at: https://github.com/leosvelperez/issue-21698. The steps I followed:

As I mentioned in the previous message, the error you're getting only happens when building the task graph for running a command. The task graph would only try to add tasks that are either the main task being run (e.g. nx serve extranet --configuration development => extranet:serve:development) and any task it depends on. According to the configuration files you've shared, the extranet:serve target doesn't depend on any other task (no dependsOn and no targetDefaults), so, the Nx shouldn't be trying to add a task named workspace:serve to the task graph.

For example, that error is expected if I try to run nx serve workspace, or if extranet had a dependency on workspace and the serve target had a ^serve dependency. That's not the case of your project based on the configurations provided.

We're going to need a reproduction so we can troubleshoot this. I've already asked everything that comes to mind and you've kindly replied with the information requested, but it hasn't been enough to reproduce the issue.

As a last sanity-check and just in case, you could additionally check:

bjornharvold commented 7 months ago

Morning @leosvelperez 🦸‍♂️

Thank you for looking into this in detail. Let me get back to you shortly with something more actionable.

🍺🍿

bjornharvold commented 7 months ago

Ok... here's what I found:

  1. Nx starts serving the moment I remove project.json at the root. @edbzn Is there another way to do this configuration in your v5.x of jscutlery/semver plugin?
  2. My app project.json was missing "defaultConfiguration": "development" under serve. That lead me further.
  3. Works: npx nx serve extranet, Fails: npx nx serve --project=extranet => Cannot find configuration for task workspace:serve
  4. Remove root project.json with the workspace and npx nx serve --project=extranet works.

Hope this helps. I am no longer blocked by this but is still quite interesting.

edbzn commented 7 months ago

@bjornharvold you could try to use the plugin API to dynamically generate the workspace project, maybe it would work but yeah not sure to understand the underlying issue, for example Nx is also generating a root project.json for Verdaccio so the issue should exist with it as well.

leosvelperez commented 7 months ago

@bjornharvold thanks for the extra information. Unfortunately, I still can't reproduce it in the repo I linked in https://github.com/nrwl/nx/issues/21698#issuecomment-1943889394. Both npx nx serve extranet and npx nx serve --project=extranet succeed with the root project.json in that repo. Both commands are actually parsed to the same args and run the same Nx command. I can't think of a reason for having any differences between those runs.

bjornharvold commented 7 months ago

Hi @leosvelperez

Add --host localhost [for example]

leosvelperez commented 7 months ago

That does the trick. I can reproduce it now and I can see what's going on. A change was made and released in Nx 18 that indeed changed how the nx <target> ... command is parsed. Please note that notation is actually a shorthand for nx run <project>:<target> and the intended way of using it is by running nx <target> <project> and not nx <target> --project <project>. I failed to recognize that previously. You should definitely use nx serve extranet in your workflow. I'm unsure if the support for nx serve --project extranet was unintended and it worked only as a side effect of a not accurate command definition.

I'll inquire internally about this one and I'll get back to you with either a fix or a confirmation that nx <target> --project <project> was not intended to be used.

brugomes commented 6 months ago

I'm also getting the same error when I try to build with docker. In my case, I'm using @nx/nuxt plugin.

nx.json

{
  "$schema": "./node_modules/nx/schemas/nx-schema.json",
  "namedInputs": {
    "default": ["{projectRoot}/**/*", "sharedGlobals"],
    "production": [
      "default",
      "!{projectRoot}/.eslintrc.json",
      "!{projectRoot}/eslint.config.js",
      "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
      "!{projectRoot}/tsconfig.spec.json"
    ],
    "sharedGlobals": []
  },
  "plugins": [
    {
      "plugin": "@nx/nuxt/plugin",
      "options": {
        "buildTargetName": "build",
        "serveTargetName": "serve",
        "serveStaticTargetName": "serve-static"
      }
    },
    {
      "plugin": "@nx/vite/plugin",
      "options": {
        "buildTargetName": "build",
        "previewTargetName": "preview",
        "testTargetName": "test",
        "serveTargetName": "serve",
        "serveStaticTargetName": "serve-static"
      }
    },
    {
      "plugin": "@nx/eslint/plugin",
      "options": {
        "targetName": "lint"
      }
    }
  ]
}

project.json

{
  "name": "my-app",
  "$schema": "../../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/my-app/src",
  "targets": {
    "container": {
      "executor": "@nx-tools/nx-container:build",
      "dependsOn": ["build"],
      "options": {
        "engine": "docker",
        "metadata": {
          "images": ["my-app"],
          "load": true,
          "tags": [
            "type=schedule",
            "type=ref,event=branch",
            "type=ref,event=tag",
            "type=ref,event=pr",
            "type=sha,prefix=sha-"
          ]
        }
      }
    }
  }
}

Dokerfile

FROM node:18

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

WORKDIR /usr/src/app

COPY package.json pnpm-lock.yaml ./

RUN --mount=type=cache,id=pnpm,target=/pnpm/store npm install -g pnpm && pnpm install --frozen-lockfile
RUN pnpm add -g nx@latest @nx/nuxt

COPY ./apps/my-app .

RUN nx run my-app:build

EXPOSE $PORT

CMD ["pnpm", "run", "preview", "--host"]

Error

RUN nx run my-app:build
NX Cannot find configuration for task my-app:build
leosvelperez commented 5 months ago

As mentioned in https://github.com/nrwl/nx/issues/21698#issuecomment-1946080056, the two intended ways of running targets are:

I've confirmed internally that nx <target> --project=<project> was never intended to work, so if you're using that syntax, please start using one of the above instead.


@brugomes, that's a different issue unrelated to the one discussed here. If you still have an issue, please create a new issue with the context so we can troubleshoot it.

Nazar-Brunarskyi commented 4 months ago

Maybe someone has already run into that kind of problem I want to Dockerize my next js app for this I have created a docker file:

FROM node:18.18.2-alpine

WORKDIR /usr/src/apps

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 4200

CMD ["npm", "run", "web:serve:qa"]

to build an image i use $ docker build -f Dockerfile.web -t web .command.

The Image is built successfully.

when I try to run a container from that image i get an error

> npx nx run web:serve:qa
 NX   Cannot find configuration for task web:serve
Pass --verbose to see the stacktrace.
i tried using setup-docker from NX but it also gives me a lot of errors
github-actions[bot] commented 3 months ago

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.