Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implicitDependencies added for a project, cause other projects to build #9426

Closed
sanderson-ut opened this issue Mar 21, 2022 · 7 comments
Closed

Comments

@sanderson-ut
Copy link

sanderson-ut commented Mar 21, 2022

Say I have 3 packages, a, b, and c. c depends on b, which is our GraphQL client.

workspace
| a
| b <- c

I add an implicitDependency on my project's GraphQL schema.json in nx.json as per the docs, like so:

  "implicitDependencies": {
    "package.json": {
      "dependencies": "*",
      "devDependencies": "*"
    },
    "config/schema.graphql": [ "b" ]
  },

I would expect that changing config/schema.graphql would not cause a to rebuild, however, I see in Nx Cloud that the GraphQL schema is added to the implicitDeps for this project and so whenever the schema changes the cache misses for a.

This is a simplified example, the actual workspace has ~150 projects, and ~50 of them depend on the GraphQL client.

Am I misunderstanding how to use implicit dependencies?

Current Behavior

a reports a cache miss and rebuilds when the implicit dependency for another project (GraphQL schema) changes.

Expected Behavior

a builds from the cache when the implicit dependency changes.

I'm unsure if this is a regression.

Steps to Reproduce

Example repo demonstrates similar behaviour: nrwl/nx-examples#194

Adding implicit dependency on example-schema.json for products causes both products and cart to build when example-schema.json changes.

Failure Logs

Environment

>  NX  Report complete - copy this into the issue template

  Node : 14.16.0
  OS   : darwin x64
  yarn : 2.4.1
  
  nx : 13.4.3
  @nrwl/angular : undefined
  @nrwl/cli : 13.4.3
  @nrwl/cypress : undefined
  @nrwl/devkit : 13.8.4
  @nrwl/eslint-plugin-nx : undefined
  @nrwl/express : undefined
  @nrwl/jest : 13.8.4
  @nrwl/linter : 13.8.4
  @nrwl/nest : undefined
  @nrwl/next : undefined
  @nrwl/node : undefined
  @nrwl/nx-cloud : 13.1.4
  @nrwl/react : undefined
  @nrwl/react-native : undefined
  @nrwl/schematics : undefined
  @nrwl/tao : 13.4.3
  @nrwl/web : undefined
  @nrwl/workspace : 13.4.3
  @nrwl/storybook : undefined
  @nrwl/gatsby : undefined
  typescript : 3.9.9
  rxjs : 6.6.7
  ---------------------------------------
  Community plugins:
  	 @angular/animations: 10.2.5
  	 @angular/cdk: 10.2.7
  	 @angular/common: 10.2.5
  	 @angular/compiler: 10.2.5
  	 @angular/compiler-cli: 10.2.5
  	 @angular/core: 10.2.5
  	 @angular/elements: 10.2.5
  	 @angular/forms: 10.2.5
  	 @angular/localize: 10.2.5
  	 @angular/platform-browser: 10.2.5
  	 @angular/platform-browser-dynamic: 10.2.5
  	 @angular/router: 10.2.5
  	 @angular/upgrade: 10.2.5
  	 @ng-bootstrap/ng-bootstrap: 8.0.4
  	 @ngrx/data: 10.1.2
  	 @ngrx/effects: 10.1.2
  	 @ngrx/entity: 10.1.2
  	 @ngrx/router-store: 10.1.2
  	 @ngrx/store: 10.1.2
  	 @ngrx/store-devtools: 10.1.2
  	 apollo-angular: 1.10.0
  	 @angular-builders/custom-webpack: 10.0.1
  	 @angular-builders/jest: 10.0.1
  	 @angular-devkit/build-angular: 0.1002.3
  	 @angular-devkit/build-ng-packagr: 0.1002.3
  	 @angular/cli: 10.2.3
  	 @angular/language-service: 10.2.5
@FrozenPandaz
Copy link
Collaborator

I agree. Creating implicit dependencies for a project should not cause all projects to be affected.

Correct me if I'm wrong but this shouldn't impact you after this change is made.
After this commit, changing config/schema.graphql will only cause b and c to rebuild, not a.

This makes it not as severe of an issue. But ideally, yes we should be able to only affect b (and it's consumers) by adding an implicitDependency to b

@sanderson-ut
Copy link
Author

I agree. Creating implicit dependencies for a project should not cause all projects to be affected.

Correct me if I'm wrong but this shouldn't impact you after this change is made. After this commit, changing config/schema.graphql will only cause b and c to rebuild, not a.

This makes it not as severe of an issue. But ideally, yes we should be able to only affect b (and it's consumers) by adding an implicitDependency to b

Hi @FrozenPandaz, thanks for your reply. The issue I see is that when nx run-many --target=build --all is run, a rebuilds due to a cache miss, whenever there is a change to config/schema.graphql. Although a does not depend on the GraphQL schema, config/schema.graphql is added to the cache key for a.

Though, it sounds like that is intended behaviour? I.e, adding an implicit dependency only changes the projects that are "affected" and not the cache?

My use case is that the GraphQL schema changes daily so the workflow for developers on my team is to pull down the latest master and build everything from scratch before starting development, relying on NX Cloud to maximise cache re-use as much as possible.

@sanderson-ut
Copy link
Author

We have temporarily got around it by creating a new explicit packages (@namespace/graphql-schema) with a symlink to the GraphQL Schema, and making every package that depends on GraphQL explicitly depend on this package.

@github-actions
Copy link

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
If we missed this issue please reply to keep it active.
Thanks for being a part of the Nx community! 🙏

@SvenEV-bakerhughes
Copy link

SvenEV-bakerhughes commented Jan 24, 2023

I am facing the same issue. In my case there are two projects:

  • backend (our desktop app)
  • setup-backend (the setup for the desktop app)

where "setup-backend" has a dependency on "backend".

The setup incorporates an environment variable that is specified in a ".env" file in the root of the Nx workspace. Thus, we want "setup-backend" to be rebuilt when the ".env" file changes, but "backend" should not be rebuilt in this case. To achieve this, I have specified this dependency in "nx.json":

{
  "implicitDependencies": {
    ".env": [
      "setup-backend"
    ]
  },
  // ...
}

Expected behavior: Changing the ".env" file only causes a cache miss in the "setup-backend" project.
Actual behavior: Changing the ".env" file causes cache misses in both projects.

@FrozenPandaz I understand that adding the implicit dependency causes cache misses in all projects. That's okay. The problem is that changing the ".env" file does this too.

Environment
 >  NX   Report complete - copy this into the issue template

   Node : 14.16.1
   OS   : win32 x64
   npm  : 6.14.12

   nx : 13.9.7
   @nrwl/angular : Not Found
   @nrwl/cypress : Not Found
   @nrwl/detox : Not Found
   @nrwl/devkit : 13.9.7
   @nrwl/eslint-plugin-nx : 13.9.7
   @nrwl/express : Not Found
   @nrwl/jest : 13.9.7
   @nrwl/js : Not Found
   @nrwl/linter : 13.9.7
   @nrwl/nest : Not Found
   @nrwl/next : Not Found
   @nrwl/node : Not Found
   @nrwl/nx-cloud : Not Found
   @nrwl/nx-plugin : Not Found
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : Not Found
   @nrwl/web : Not Found
   @nrwl/workspace : 13.9.7
   typescript : 4.5.5
   rxjs : 6.6.7
   ---------------------------------------
   Community plugins:

@SvenEV-bakerhughes
Copy link

I found a workaround for my scenario that avoids the implicitDependencies construct in "nx.json" altogether and instead leverages implicit dependencies on "project.json" level.

I added a third project called "props" and moved the ".env" file there. (The project has no targets defined.)
In "setup-backend", I added an implicit dependency on the "props" project and leveraged the "envFile" property of the run-commands builder to load the file at "props/.env":

// setup_backend's project.json
{
    "name": "setup-backend",
    "root": "setup-backend",
    "implicitDependencies": [ "backend", "props" ], // <= dependency on "props" ensures cache invalidation on .env changes
    "targets": {
        "build": {
            "executor": "@nrwl/workspace:run-commands",
            "options": {
                "envFile": "props/.env", // <= import .env file from other project
                "command": "..."
            },
            "dependsOn": [
                {
                    "projects": "dependencies",
                    "target": "build"
                }
            ]
        }
    }
}

This way, "setup-backend" gets rebuilt whenever "props/.env" changes, but "backend" does not.

@github-actions
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants