Closed bjornharvold closed 1 year ago
Hm, we need to look more into this.
Could you provide the executor being used to build the projects? Is it reproducible with a single project? If possible, could you please provide a repro?
Hi @FrozenPandaz
Here's a project.json from one of our 10 apps (all configured the same way) and 2000+ module Nx monorepo.
{
"name": "administration",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "apps/administration/src",
"prefix": "wink",
"targets": {
"build": {
"executor": "@nx/angular:webpack-browser",
"outputs": ["{options.outputPath}"],
"options": {
"buildLibsFromSource": true,
"allowedCommonJsDependencies": [
"hammerjs",
"clone-deep",
"flat",
"fast-sha256",
"rfdc"
],
"baseHref": "/",
"outputPath": "dist/apps/administration",
"index": "apps/administration/src/index.html",
"main": "apps/administration/src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "apps/administration/tsconfig.app.json",
"stylePreprocessorOptions": {
"includePaths": []
},
"assets": [
"apps/administration/src/assets",
"apps/administration/src/manifest.json",
"apps/administration/src/robots.txt"
],
"styles": [
"node_modules/npm-font-open-sans/open-sans.css",
"apps/administration/src/assets/styles/traveliko.css",
"shared-styles/administration/theme/default/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/administration/src/environments/environment.ts",
"with": "apps/administration/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,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "3mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "25kb",
"maximumError": "30kb"
}
],
"serviceWorker": true,
"ngswConfigPath": "apps/administration/ngsw-config.json"
},
"staging": {
"fileReplacements": [
{
"replace": "apps/administration/src/environments/environment.ts",
"with": "apps/administration/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,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "3mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "25kb",
"maximumError": "30kb"
}
],
"serviceWorker": true,
"ngswConfigPath": "apps/administration/ngsw-config.json"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"executor": "@nx/angular:webpack-dev-server",
"configurations": {
"development": {
"browserTarget": "administration:build:development"
},
"production": {
"browserTarget": "administration:build:production"
}
}
},
"extract-i18n": {
"executor": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "administration:build"
}
},
"lint": {
"executor": "@nx/linter:eslint",
"options": {
"lintFilePatterns": [
"apps/administration/src/**/*.ts",
"apps/administration/src/**/*.html"
]
},
"outputs": ["{options.outputFile}"]
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/apps/administration"],
"options": {
"jestConfig": "apps/administration/jest.config.ts",
"passWithNoTests": true
}
}
},
"tags": ["domain:administration", "type:app"]
}
Here's a project.json from one of our libraries (also configured identically):
{
"name": "account-consumer",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "libs/account/consumer/src",
"prefix": "wink",
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"outputs": ["{workspaceRoot}/dist/libs/account/consumer"],
"options": {
"project": "libs/account/consumer/ng-package.json",
"updateBuildableProjectDepsInPackageJson": true
},
"configurations": {
"production": {
"tsConfig": "libs/account/consumer/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "libs/account/consumer/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/libs/account/consumer"],
"options": {
"jestConfig": "libs/account/consumer/jest.config.ts",
"passWithNoTests": true
}
},
"lint": {
"executor": "@nx/linter:eslint",
"options": {
"lintFilePatterns": [
"libs/account/consumer/**/*.ts",
"libs/account/consumer/**/*.html"
]
}
}
},
"tags": ["domain:account-consumer", "type:domain-consumer-logic"]
}
Are you saying by just creating a Angular package-based monorepo with the 2 versions mentioned above does not show you the difference in build times? If so, I will do my best to create something to reproduce this.
Cheers
Hey @bjornharvold
I tried to reproduce this but was unable to. If you're able to provide a reproduction repo, that would be very helpful
Hi @Coly010
Sure thing. I looked into it and could also not replicate with a fresh install of Nx with 16.5.3 and 16.7.2 so I continued doing some digging.
From:
"namedInputs": {
"default": [
"{projectRoot}/**/*",
"sharedGlobals"
],
"sharedGlobals": [
"{workspaceRoot}/workspace.json"
],
"production": [
"default",
"!{projectRoot}/.storybook/**/*",
"!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)",
"!{projectRoot}/tsconfig.storybook.json",
"!{projectRoot}/src/test-setup.[jt]s"
]
}
To (taken from the fresh install sans the storybook stuff:
"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"
]
}
But I did also find the real issue: We have a 2000+ module monorepo with 11 apps and the rest libraries. If you type:
npx nx run-many -t build
It will take over a minute to read in the entire project graph in memory before Nx starts building anything. When it does start building, you'll see build times like these:
✔ nx run shared-util-tokens:build:production (7s)
✔ nx run key-value-domain:build:production (8s)
✔ nx run shared-ui-ghost-loading-element:build:production (9s)
If we, instead, execute a more limited build like this:
npx nx run-many -t build -p app1
It takes less than 25% of the time to read the project graph in memory and build times look like this:
✔ nx run shared-util-tokens:build:production (3s)
✔ nx run key-value-domain:build:production (3s)
✔ nx run shared-ui-ghost-loading-element:build:production (3s)
If we start adding projects to -p, it starts slowing down again. So, I do think that, due to the size of the monorepo AND a change in your codebase from 16.5.3 to v16.6.x that caused our build to slow down. And, I think it has something to do with the in-memory project graph / cache manager.
The shorty-term solution is just to build our apps individually and leverage the Nx Cache.
I'll let you guys do with ticket as you wish. Our build is back up to speed at least.
Glad to hear your build speed is back to normal!
But thank you for the information, this is very helpful.
When I tried it out locally, i used the updateBuildableProjectDepsInPackageJson
property also, but couldn't see any difference, so I think you could be closer to the issue with it being related to the project-graph.
It's another avenue for me to investigate at least. Thank you!
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! 🙏
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.
Current Behavior
I don't consider this a bug. Nx builds fine. But the last 2 version of Nx (at latest with Angular) build times have increased significantly.
Expected Behavior
Build times on Nx 16.5.3 on identical code base
✔ nx run key-value-domain:build:production (2s) ✔ nx run shared-util-tokens:build:production (2s) ✔ nx run shared-ui-ghost-loading-element:build:production (2s) ✔ nx run authentication-util-authenticated-guard:build:production (2s) ✔ nx run lifestyle-domain:build:production (2s) ✔ nx run shared-ui-no-result-box:build:production (2s) ✔ nx run currency-domain:build:production (1s) ✔ nx run shared-ui-loading-indicator:build:production (2s) ✔ nx run shared-ui-create-button:build:production (2s) ✔ nx run shared-ui-switch-form:build:production (2s) ✔ nx run crud-publisher:build:production (2s) ✔ nx run form-publisher:build:production (2s) ✔ nx run uuid-publisher:build:production (2s) ✔ nx run shared-ui-hint-card:build:production (2s) ✔ nx run shared-ui-required-field-indicator:build:production (2s) ✔ nx run dynamic-component-loader-domain:build:production (1s) ✔ nx run persistent-entity-publisher:build:production (1s) ✔ nx run media-util-cloudinary-url-pipe:build:production (2s) ✔ nx run google-maps-domain:build:production (2s) ✔ nx run currency-util-formatted-currency-pipe:build:production (2s)
GitHub Repo
No response
Steps to Reproduce
Compare the difference in build time
Nx Report
Failure Logs
No response
Operating System
Additional Information
I mentioned this in the Nx Angular Slack channel here: https://nrwlcommunity.slack.com/archives/C016ASCS683/p1691660639502029
The last minor update came with a migration step that added something to the configuration of all modules and now this warning appears when building:
Option "updateBuildableProjectDepsInPackageJson" is deprecated: Configure the project to use the '@nx/dependency-checks' ESLint rule instead (https://nx.dev/packages/eslint-plugin/documents/dependency-checks). It will be removed in v17.
Is this the culprit?