Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f16d87920b | |||
| 97fb1f0f2c | |||
| a72fd16d01 | |||
| 8a18071877 | |||
| 9679351866 | |||
| 830e22583b | |||
| fc0543087b | |||
| 93b4210265 | |||
| ab688fcc06 | |||
| 1507695452 | |||
| 0d7737649d | |||
| a7957765cc | |||
| ebf6bb701b | |||
| 67140ee5f9 | |||
| 056243fe35 | |||
| 706d56f6fa | |||
| 78abb5c5a2 | |||
| c8f2cc8e9b | |||
| cac58fafbc | |||
| 9047441cd3 | |||
| 4c8d01d22b | |||
| 8f2e526d22 |
@@ -20,8 +20,6 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.node_version }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -55,10 +53,11 @@ jobs:
|
||||
|
||||
- name: Setup dev tools with mise
|
||||
uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.node_version }}
|
||||
|
||||
- name: Enable corepack and install pnpm
|
||||
run: |
|
||||
npm install -g corepack@latest
|
||||
corepack enable
|
||||
corepack prepare --activate
|
||||
|
||||
@@ -138,8 +137,6 @@ jobs:
|
||||
contents: read
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 200 # <- cap each job to 200 minutes
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.node_version }}
|
||||
strategy:
|
||||
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} # Load matrix from previous job
|
||||
fail-fast: false
|
||||
@@ -157,10 +154,11 @@ jobs:
|
||||
|
||||
- name: Setup dev tools with mise
|
||||
uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.node_version }}
|
||||
|
||||
- name: Enable corepack and install pnpm
|
||||
run: |
|
||||
npm install -g corepack@latest
|
||||
corepack enable
|
||||
corepack prepare --activate
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ out
|
||||
.rustup/
|
||||
target
|
||||
.flattened-pom.xml
|
||||
dependency-reduced-pom.xml
|
||||
*.wasm
|
||||
/wasi-sdk*
|
||||
|
||||
@@ -76,7 +75,6 @@ storybook-static
|
||||
.kotlin
|
||||
|
||||
.claude/settings.local.json
|
||||
CLAUDE.local.md
|
||||
|
||||
.cursor/mcp.json
|
||||
|
||||
@@ -133,4 +131,3 @@ test-results
|
||||
# .NET build output
|
||||
/packages/dotnet/analyzer/bin
|
||||
/packages/dotnet/analyzer/obj
|
||||
/*.deb
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
wrapperVersion=3.3.4
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/4.0.0-rc-5/apache-maven-4.0.0-rc-5-bin.zip
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"endOfLine": "lf",
|
||||
"trailingComma": "es5",
|
||||
"plugins": ["prettier-plugin-tailwindcss"],
|
||||
"overrides": [
|
||||
{
|
||||
|
||||
@@ -9,25 +9,6 @@ When responding to queries about this repository:
|
||||
Always strive to provide accurate, helpful responses that align with the best practices and workflows described in this
|
||||
file.
|
||||
|
||||
## Documentation Contributions
|
||||
|
||||
When working on Nx documentation, all documentation content lives in the `astro-docs/` folder. This is the new Astro-based documentation site built with Starlight.
|
||||
|
||||
**Important**: Before making any documentation changes, read the `astro-docs/README.md` file for detailed guidance on:
|
||||
|
||||
- Project structure and architecture
|
||||
- Content types (regular docs, dynamic plugin docs, CLI docs)
|
||||
- Available Markdoc tags for rich content
|
||||
- Development workflow and commands
|
||||
- Sidebar management
|
||||
|
||||
### Quick Reference
|
||||
|
||||
- Documentation content: `astro-docs/src/content/docs/`
|
||||
- Use `.mdoc` (Markdoc) or `.mdx` format for documentation files
|
||||
- Run `nx serve astro-docs` to start the local dev server
|
||||
- Sidebar structure is defined in `astro-docs/sidebar.mts`
|
||||
|
||||
## GitHub Issue Response Mode
|
||||
|
||||
When responding to GitHub issues, determine your approach based on how the request is phrased:
|
||||
@@ -211,4 +192,13 @@ Fixes #ISSUE_NUMBER
|
||||
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
|
||||
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
|
||||
|
||||
# CI Error Guidelines
|
||||
|
||||
If the user wants help with fixing an error in their CI pipeline, use the following flow:
|
||||
|
||||
- Retrieve the list of current CI Pipeline Executions (CIPEs) using the `nx_cloud_cipe_details` tool
|
||||
- If there are any errors, use the `nx_cloud_fix_cipe_failure` tool to retrieve the logs for a specific task
|
||||
- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary
|
||||
- Make sure that the problem is fixed by running the task that you passed into the `nx_cloud_fix_cipe_failure` tool
|
||||
|
||||
<!-- nx configuration end-->
|
||||
|
||||
@@ -9,25 +9,6 @@ When responding to queries about this repository:
|
||||
Always strive to provide accurate, helpful responses that align with the best practices and workflows described in this
|
||||
file.
|
||||
|
||||
## Documentation Contributions
|
||||
|
||||
When working on Nx documentation, all documentation content lives in the `astro-docs/` folder. This is the new Astro-based documentation site built with Starlight.
|
||||
|
||||
**Important**: Before making any documentation changes, read the `astro-docs/README.md` file for detailed guidance on:
|
||||
|
||||
- Project structure and architecture
|
||||
- Content types (regular docs, dynamic plugin docs, CLI docs)
|
||||
- Available Markdoc tags for rich content
|
||||
- Development workflow and commands
|
||||
- Sidebar management
|
||||
|
||||
### Quick Reference
|
||||
|
||||
- Documentation content: `astro-docs/src/content/docs/`
|
||||
- Use `.mdoc` (Markdoc) or `.mdx` format for documentation files
|
||||
- Run `nx serve astro-docs` to start the local dev server
|
||||
- Sidebar structure is defined in `astro-docs/sidebar.mts`
|
||||
|
||||
## GitHub Issue Response Mode
|
||||
|
||||
When responding to GitHub issues, determine your approach based on how the request is phrased:
|
||||
@@ -211,4 +192,13 @@ Fixes #ISSUE_NUMBER
|
||||
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
|
||||
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
|
||||
|
||||
# CI Error Guidelines
|
||||
|
||||
If the user wants help with fixing an error in their CI pipeline, use the following flow:
|
||||
|
||||
- Retrieve the list of current CI Pipeline Executions (CIPEs) using the `nx_cloud_cipe_details` tool
|
||||
- If there are any errors, use the `nx_cloud_fix_cipe_failure` tool to retrieve the logs for a specific task
|
||||
- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary
|
||||
- Make sure that the problem is fixed by running the task that you passed into the `nx_cloud_fix_cipe_failure` tool
|
||||
|
||||
<!-- nx configuration end-->
|
||||
|
||||
+2
-3
@@ -148,6 +148,7 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
# Misc
|
||||
/e2e/lerna-smoke-tests/** @vsavkin @JamesHenry
|
||||
/e2e/utils/** @meeroslav @nrwl/nx-testing-tools-reviewers @vsavkin
|
||||
/community @nrwl/nx-docs-reviewers
|
||||
/CONTRIBUTING.md @FrozenPandaz
|
||||
/CODE_OF_CONDUCT.md @FrozenPandaz
|
||||
/CODEOWNERS @FrozenPandaz @AgentEnder
|
||||
@@ -164,12 +165,10 @@ mise.toml @nrwl/nx-pipelines-reviewers @FrozenPandaz
|
||||
/.husky/** @nrwl/nx-pipelines-reviewers
|
||||
/packages/workspace/src/generators/ci-workflow/** @nrwl/nx-pipelines-reviewers
|
||||
|
||||
# AI Agent Integration
|
||||
# Claude AI Integration
|
||||
CLAUDE.md @FrozenPandaz @Coly010
|
||||
.claude/** @FrozenPandaz @Coly010
|
||||
.mcp.json @FrozenPandaz @Coly010
|
||||
AGENTS.md @FrozenPandaz @Coly010
|
||||
.gemini @FrozenPandaz @Coly010
|
||||
|
||||
# Global Files
|
||||
project.json @FrozenPandaz @vsavkin
|
||||
|
||||
Generated
+21
-138
@@ -747,16 +747,6 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||
|
||||
[[package]]
|
||||
name = "dispatch2"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
@@ -1587,7 +1577,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.57.0",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1981,9 +1971,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.180"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -2430,7 +2420,6 @@ dependencies = [
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"static_assertions",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_dep_graph",
|
||||
@@ -2461,9 +2450,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.6.3"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
|
||||
checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59"
|
||||
dependencies = [
|
||||
"objc2-encode",
|
||||
]
|
||||
@@ -2482,12 +2471,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-foundation"
|
||||
version = "0.3.2"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||
checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"dispatch2",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
@@ -2520,16 +2508,6 @@ dependencies = [
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-surface"
|
||||
version = "0.3.0"
|
||||
@@ -2569,7 +2547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3868,15 +3846,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.37.2"
|
||||
version = "0.33.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f"
|
||||
checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"rayon",
|
||||
"windows",
|
||||
]
|
||||
|
||||
@@ -4822,24 +4800,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.3"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core 0.61.2",
|
||||
"windows-future",
|
||||
"windows-link",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4848,36 +4814,12 @@ version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement 0.57.0",
|
||||
"windows-interface 0.57.0",
|
||||
"windows-result 0.1.2",
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
dependencies = [
|
||||
"windows-implement 0.60.2",
|
||||
"windows-interface 0.59.3",
|
||||
"windows-link",
|
||||
"windows-result 0.3.4",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
@@ -4889,17 +4831,6 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
@@ -4911,32 +4842,11 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link",
|
||||
]
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
@@ -4947,24 +4857,6 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
@@ -5047,15 +4939,6 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
||||
+4
-51
@@ -36,9 +36,9 @@ astro-docs/
|
||||
│ │ ├── markdoc/ # Markdoc tag components
|
||||
│ │ └── utils/ # Utility functions
|
||||
│ ├── content/ # Documentation content
|
||||
│ │ ├── banner.json # Banner collection (generated by prebuild-banner)
|
||||
│ │ ├── docs/ # Main documentation files (.mdoc, .mdx)
|
||||
│ │ └── approved-community-plugins.json # Powers plugin registry
|
||||
│ │ ├── approved-community-plugins.json # Powers plugin registry
|
||||
│ │ └── notifications.json # Notifications banners for docs site
|
||||
│ ├── pages/ # Dynamic pages and routes (e.g. devkit)
|
||||
│ ├── plugins/ # Content loaders and plugins
|
||||
│ │ ├── *.loader.ts # Dynamic content loaders (e.g. CLI commands and API docs generation)
|
||||
@@ -66,11 +66,13 @@ The site uses custom content loaders to dynamically generate documentation:
|
||||
### Content Types
|
||||
|
||||
1. **Regular Documentation** (`src/content/docs/`)
|
||||
|
||||
- Written in `.mdoc` (Markdoc) or `.mdx` (MDX) format
|
||||
- Organized by sections: getting-started, concepts, guides, api
|
||||
- File-based routing (filename = URL path)
|
||||
|
||||
2. **Dynamic Plugin Documentation**
|
||||
|
||||
- Auto-generated from Nx packages
|
||||
- Includes generators, executors, and migrations
|
||||
- Updated during build process
|
||||
@@ -231,52 +233,3 @@ export const sidebar = [
|
||||
- Navigation structure
|
||||
- Section organization
|
||||
- Dynamic content injection points
|
||||
|
||||
## Banner Configuration
|
||||
|
||||
The floating banner promotes events/webinars. It's fetched at **build time** from a Framer CMS page and stored as an Astro content collection.
|
||||
|
||||
### Setup
|
||||
|
||||
Set `BANNER_URL` to point to a Framer page that renders banner JSON:
|
||||
|
||||
```
|
||||
BANNER_URL=https://your-framer-site.framer.app/api/banners/main
|
||||
```
|
||||
|
||||
The Framer page should render JSON inside a `<pre>` tag:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Event Title",
|
||||
"description": "Event description",
|
||||
"primaryCtaUrl": "https://...",
|
||||
"primaryCtaText": "Learn More",
|
||||
"secondaryCtaUrl": "",
|
||||
"secondaryCtaText": "",
|
||||
"enabled": true,
|
||||
"activeUntil": "2025-12-31T00:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Schema
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| ------------------ | -------- | -------- | ------------------------- |
|
||||
| `title` | string | Yes | Banner headline |
|
||||
| `description` | string | Yes | Banner body text |
|
||||
| `primaryCtaUrl` | string | Yes | Primary button URL |
|
||||
| `primaryCtaText` | string | Yes | Primary button text |
|
||||
| `secondaryCtaUrl` | string | No | Secondary button URL |
|
||||
| `secondaryCtaText` | string | No | Secondary button text |
|
||||
| `enabled` | boolean | Yes | Show/hide the banner |
|
||||
| `activeUntil` | ISO 8601 | No | Auto-hide after this date |
|
||||
|
||||
### Behavior
|
||||
|
||||
- Banner is fetched during `prebuild-banner` target and saved to `src/content/banner.json` as a collection (array)
|
||||
- Uses Astro content collection with `file()` loader and schema validation
|
||||
- Requires rebuild/redeploy to update the banner
|
||||
- Users can dismiss the banner (stored in localStorage)
|
||||
- If `enabled` is `false` or `activeUntil` has passed, the banner won't show
|
||||
- If `BANNER_URL` is not set, an empty collection is generated
|
||||
|
||||
@@ -22,7 +22,7 @@ const PUBLIC_CONFIG = {
|
||||
export default defineConfig({
|
||||
base: BASE,
|
||||
vite: { plugins: [tailwindcss()] },
|
||||
// Allow this to be configured per environment for robots.txt detection
|
||||
// Allow this to be configured per environment
|
||||
// Note: this happens during build time so we don't use `import.meta.env`
|
||||
site: process.env.NX_DEV_URL ?? 'https://nx.dev',
|
||||
image: {
|
||||
@@ -82,6 +82,7 @@ export default defineConfig({
|
||||
],
|
||||
plugins: [],
|
||||
routeMiddleware: [
|
||||
'./src/plugins/banner.middleware.ts',
|
||||
// NOTE: this is responsibile for populating the Reference section
|
||||
// with generated routes from the nx-reference-packages content collection
|
||||
// since the sidebar doesn't auto generate w/ dynamic routes from src/pages/reference
|
||||
@@ -90,8 +91,6 @@ export default defineConfig({
|
||||
'./src/plugins/sidebar-icons.middleware.ts',
|
||||
'./src/plugins/og.middleware.ts',
|
||||
'./src/plugins/github-stars.middleware.ts',
|
||||
'./src/plugins/raw-content.middleware.ts',
|
||||
'./src/plugins/canonical.middleware.ts',
|
||||
],
|
||||
markdown: {
|
||||
// this breaks the renderMarkdown function in the plugin loader due to starlight path normalization
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
# Disable gradle and maven plugins on Netlify
|
||||
# (Netlify only supports Java 8 but these plugins require Java 17)
|
||||
[build.environment]
|
||||
NX_GRADLE_DISABLE = "true"
|
||||
NX_MAVEN_DISABLE = "true"
|
||||
|
||||
# Permanent redirects (301 by default)
|
||||
|
||||
# Storybook docs consolidation
|
||||
|
||||
@@ -3,22 +3,9 @@
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"comment": "package.json#scripts runs in the project root directory with astro assumes is where the node_modules is. which fails. so run the scripts in project.json#targets with --root command instead",
|
||||
"targets": {
|
||||
"prebuild-banner": {
|
||||
"cache": false,
|
||||
"outputs": ["{projectRoot}/src/content/banner.json"],
|
||||
"command": "node ../scripts/documentation/prebuild-banner.mjs",
|
||||
"options": {
|
||||
"cwd": "astro-docs",
|
||||
"env": {
|
||||
"BANNER_OUTPUT_PATH": "src/content/banner.json",
|
||||
"BANNER_ENV_VAR": "BANNER_URL"
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"continuous": true,
|
||||
"dependsOn": [
|
||||
"prebuild-banner",
|
||||
{
|
||||
"projects": ["devkit", "create-nx-workspace", "dotnet", "maven"],
|
||||
"target": "build"
|
||||
@@ -31,18 +18,11 @@
|
||||
},
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"prebuild-banner",
|
||||
{
|
||||
"projects": ["devkit", "create-nx-workspace", "dotnet", "maven"],
|
||||
"target": "build"
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
"production",
|
||||
"^production",
|
||||
"{projectRoot}/src/content/banner.json",
|
||||
{ "env": "NX_DEV_URL" }
|
||||
],
|
||||
"outputs": [
|
||||
"{projectRoot}/dist",
|
||||
"{projectRoot}/.astro",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# *
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Host
|
||||
Host: https://nx.dev
|
||||
|
||||
# Sitemaps
|
||||
Sitemap: https://nx.dev/sitemap-index.xml
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 175 KiB |
@@ -1,124 +0,0 @@
|
||||
---
|
||||
export interface Props {
|
||||
content: string;
|
||||
}
|
||||
|
||||
const { content } = Astro.props;
|
||||
// Generate a unique ID for this instance
|
||||
const id = `copy-content-${Math.random().toString(36).slice(2, 9)}`;
|
||||
---
|
||||
|
||||
<copy-page-button data-content-id={id}>
|
||||
<button
|
||||
type="button"
|
||||
class="copy-page-btn"
|
||||
>
|
||||
<svg class="icon-default" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 7.5V6.108c0-1.135.845-2.098 1.976-2.192.373-.03.748-.057 1.123-.08M15.75 18H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08M15.75 18.75v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5A3.375 3.375 0 0 0 6.375 7.5H5.25m11.9-3.664A2.251 2.251 0 0 0 15 2.25h-1.5a2.251 2.251 0 0 0-2.15 1.586m5.8 0c.065.21.1.433.1.664v.75h-6V4.5c0-.231.035-.454.1-.664M6.75 7.5H4.875c-.621 0-1.125.504-1.125 1.125v12c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V16.5a9 9 0 0 0-9-9Z" />
|
||||
</svg>
|
||||
<svg class="icon-copied" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
<span class="label">Copy page</span>
|
||||
</button>
|
||||
<script type="application/json" id={id} set:html={JSON.stringify(content)} />
|
||||
</copy-page-button>
|
||||
|
||||
<style>
|
||||
.copy-page-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: var(--sl-text-xs);
|
||||
color: var(--sl-color-gray-3);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.copy-page-btn:hover {
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
|
||||
.copy-page-btn svg {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.copy-page-btn .icon-copied {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.copy-page-btn.copied .icon-default {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.copy-page-btn.copied .icon-copied {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
class CopyPageButtonElement extends HTMLElement {
|
||||
private button: HTMLButtonElement | null = null;
|
||||
private timeout: number | null = null;
|
||||
private content: string | null = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.button = this.querySelector('button');
|
||||
|
||||
// Get content from the JSON script tag
|
||||
const contentId = this.dataset.contentId;
|
||||
if (contentId) {
|
||||
const scriptTag = this.querySelector(`#${contentId}`);
|
||||
if (scriptTag?.textContent) {
|
||||
try {
|
||||
this.content = JSON.parse(scriptTag.textContent);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse copy content:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.button?.addEventListener('click', this.handleClick);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.button?.removeEventListener('click', this.handleClick);
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
private handleClick = async () => {
|
||||
if (!this.content) return;
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(this.content);
|
||||
this.showCopiedState();
|
||||
} catch (err) {
|
||||
console.error('Failed to copy:', err);
|
||||
}
|
||||
};
|
||||
|
||||
private showCopiedState() {
|
||||
this.button?.classList.add('copied');
|
||||
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
this.timeout = window.setTimeout(() => {
|
||||
this.button?.classList.remove('copied');
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('copy-page-button', CopyPageButtonElement);
|
||||
</script>
|
||||
@@ -266,11 +266,12 @@ function OrderButton({
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`flex items-center gap-1 rounded border px-1.5 py-0.5 font-medium transition ${
|
||||
isActive
|
||||
? 'border-blue-500 bg-blue-50 text-blue-700 dark:border-blue-400 dark:bg-blue-900/30 dark:text-blue-300'
|
||||
: 'border-slate-200 bg-white hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-800 dark:hover:bg-slate-700'
|
||||
}`}
|
||||
className={`flex items-center gap-1 rounded border px-1.5 py-0.5 font-medium transition
|
||||
${
|
||||
isActive
|
||||
? 'border-blue-500 bg-blue-50 text-blue-700 dark:border-blue-400 dark:bg-blue-900/30 dark:text-blue-300'
|
||||
: 'border-slate-200 bg-white hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-800 dark:hover:bg-slate-700'
|
||||
}`}
|
||||
onClick={() => onClick(orderKey)}
|
||||
>
|
||||
{icon}
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
---
|
||||
// Copied from https://github.com/withastro/starlight/blob/f14eb0c/packages/starlight/components/PageFrame.astro with modifications.
|
||||
import MobileMenuToggle from '@astrojs/starlight/components/MobileMenuToggle.astro';
|
||||
import { Footer } from '@nx/nx-dev-ui-common/src/lib/footer';
|
||||
import { GitHubStarWidget } from '@nx/nx-dev-ui-common/src/lib/github-star-widget';
|
||||
import { Footer, GitHubStarWidget } from '@nx/nx-dev-ui-common';
|
||||
import { WebinarNotifier } from '@nx/nx-dev-ui-common/src/lib/webinar-notifier';
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
const { hasSidebar } = Astro.locals.starlightRoute;
|
||||
const githubStarsCount = Astro.locals.githubStarsCount ?? 0;
|
||||
|
||||
// Get banner from collection
|
||||
const bannerCollection = await getCollection('banner');
|
||||
const bannerConfig = bannerCollection[0]?.data;
|
||||
|
||||
// Check if banner is active based on activeUntil date
|
||||
function isBannerActive(config: typeof bannerConfig): boolean {
|
||||
if (!config?.activeUntil) return false;
|
||||
return new Date() < new Date(config.activeUntil);
|
||||
}
|
||||
|
||||
const showBanner = isBannerActive(bannerConfig);
|
||||
const bannerId = bannerConfig ? `${bannerConfig.title}-${bannerConfig.activeUntil || 'no-expiry'}` : '';
|
||||
---
|
||||
|
||||
<div class="page sl-flex">
|
||||
@@ -63,19 +48,7 @@ const bannerId = bannerConfig ? `${bannerConfig.title}-${bannerConfig.activeUnti
|
||||
}
|
||||
<div class="main-frame"><slot /></div>
|
||||
<Footer disableThemeSwitcher={true} useDomainPrefix={true} className="dark:bg-slate-900" />
|
||||
{showBanner && bannerConfig && (
|
||||
<WebinarNotifier
|
||||
id={bannerId}
|
||||
title={bannerConfig.title}
|
||||
description={bannerConfig.description}
|
||||
primaryCtaUrl={bannerConfig.primaryCtaUrl}
|
||||
primaryCtaText={bannerConfig.primaryCtaText}
|
||||
secondaryCtaUrl={bannerConfig.secondaryCtaUrl}
|
||||
secondaryCtaText={bannerConfig.secondaryCtaText}
|
||||
activeUntil={bannerConfig.activeUntil}
|
||||
client:load
|
||||
/>
|
||||
)}
|
||||
<WebinarNotifier client:load />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import MobileMenuFooter from '@astrojs/starlight/components/MobileMenuFooter.astro'
|
||||
import SidebarPersister from '@astrojs/starlight/components/SidebarPersister.astro'
|
||||
import SidebarSublist from './SidebarSublist.astro'
|
||||
import { GitHubStarWidget } from '@nx/nx-dev-ui-common/src/lib/github-star-widget';
|
||||
import { GitHubStarWidget } from '@nx/nx-dev-ui-common';
|
||||
|
||||
const { sidebar } = Astro.locals.starlightRoute
|
||||
const githubStarsCount = Astro.locals.githubStarsCount ?? 0;
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
// recreated from https://github.com/withastro/starlight/blob/main/packages/starlight/components/TableOfContents.astro
|
||||
import TableOfContentsList from './TableOfContentsList.astro';
|
||||
import { GitHubStarWidget } from '@nx/nx-dev-ui-common';
|
||||
import CopyPageButton from '../CopyPageButton.astro';
|
||||
|
||||
const { toc } = Astro.locals.starlightRoute;
|
||||
const githubStarsCount = Astro.locals.githubStarsCount ?? 0;
|
||||
const rawContent = Astro.locals.rawContent;
|
||||
---
|
||||
|
||||
{
|
||||
@@ -21,11 +19,6 @@ const rawContent = Astro.locals.rawContent;
|
||||
<TableOfContentsList toc={toc.items} />
|
||||
</div>
|
||||
</nav>
|
||||
{rawContent && (
|
||||
<div class="copy-page-button-container">
|
||||
<CopyPageButton content={rawContent} />
|
||||
</div>
|
||||
)}
|
||||
</custom-toc>
|
||||
)
|
||||
}
|
||||
@@ -179,13 +172,6 @@ const rawContent = Astro.locals.rawContent;
|
||||
.github-star-widget-container {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Copy page button styling - positioned after TOC with divider */
|
||||
.copy-page-button-container {
|
||||
padding-top: 1rem;
|
||||
margin-top: 1rem;
|
||||
border-top: 1px solid var(--sl-color-hairline);
|
||||
}
|
||||
|
||||
/* Container with proper scrolling */
|
||||
.toc-container {
|
||||
|
||||
@@ -101,25 +101,35 @@ const communityPlugins = defineCollection({
|
||||
),
|
||||
});
|
||||
|
||||
// Banner collection for showing time-based notifications (webinars, events, etc.)
|
||||
const banner = defineCollection({
|
||||
loader: file('src/content/banner.json'),
|
||||
// general notification collection for showing time based notifications
|
||||
// in app, i.e. webinars, or confs etc.
|
||||
// goal is that different pages/parts of the app can query for their specific needs.
|
||||
// i.e. show banner for webinar, or show a dynamic sidebars item for a conf signups etc.
|
||||
const notifications = defineCollection({
|
||||
loader: file('src/content/notifications.json'),
|
||||
schema: z.object({
|
||||
id: z.string(),
|
||||
slug: z.string(),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
primaryCtaUrl: z.string(),
|
||||
primaryCtaText: z.string(),
|
||||
secondaryCtaUrl: z.string().optional(),
|
||||
secondaryCtaText: z.string().optional(),
|
||||
activeUntil: z.string(),
|
||||
// TODO(caleb): should parse this to a date object
|
||||
date: z.string(),
|
||||
// slug will be dismiss key for the banner
|
||||
slug: z.string(),
|
||||
authors: z.array(z.string()),
|
||||
// these have to contain the tag webinar??
|
||||
type: z.enum(['webinar', 'event', 'release']),
|
||||
cover_image: z.string(),
|
||||
// tbf this can probs be derived if given a full timestamp for `date`
|
||||
time: z.string(),
|
||||
// TODO(caleb); get all possible statues, some of these could be derived such as 'Upcoming' or 'Past - *'
|
||||
// we just really want to know if something is gated or not etc
|
||||
status: z.enum(['Upcoming', 'Past - Gated']),
|
||||
registrationUrl: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = {
|
||||
docs,
|
||||
banner,
|
||||
notifications,
|
||||
'nx-reference-packages': nxReferencePackages,
|
||||
'plugin-docs': pluginDocs,
|
||||
'community-plugins': communityPlugins,
|
||||
|
||||
@@ -543,10 +543,5 @@
|
||||
"name": "@gridatek/nx-supabase",
|
||||
"description": "Nx plugin for managing multiple Supabase projects and environments",
|
||||
"url": "https://github.com/gridatek/nx-supabase"
|
||||
},
|
||||
{
|
||||
"name": "@berenddeboer/nx-biome",
|
||||
"description": "A self-inferring Nx plugin for using biome to format and lint projects. Supports --batch",
|
||||
"url": "https://github.com/berenddeboer/nx-plugins/tree/main/packages/nx-biome"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": "banner",
|
||||
"activeUntil": "2025-12-26T00:00:00.000Z",
|
||||
"description": "This is the first banner's description.",
|
||||
"enabled": false,
|
||||
"primaryCtaText": "Hello from today",
|
||||
"primaryCtaUrl": "https://nx.dev",
|
||||
"title": "This is the first banner's title HEHEHEHEHE",
|
||||
"secondaryCtaText": "",
|
||||
"secondaryCtaUrl": "",
|
||||
"_generated": "2025-12-11T20:41:11.810Z"
|
||||
}
|
||||
]
|
||||
@@ -63,9 +63,9 @@ If defining a new target that needs to run a single shell command, there is a sh
|
||||
"generators": {},
|
||||
"targets": {
|
||||
"echo": {
|
||||
"command": "echo 'hello world'",
|
||||
},
|
||||
},
|
||||
"command": "echo 'hello world'"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -47,27 +47,6 @@ A typical workspace will have many plugins inferring tasks. Nx processes all the
|
||||
|
||||
Plugins are processed in the order that they appear in the `plugins` array in `nx.json`. So, if multiple plugins create a task with the same name, the plugin listed last will win. If, for some reason, you have a project with both a `vite.config.js` file and a `webpack.config.js` file, both the `@nx/vite` plugin and the `@nx/webpack` plugin will try to create a `build` task. The `build` task that is executed will be the task that belongs to the plugin listed lower in the `plugins` array.
|
||||
|
||||
### Scope Plugins to Specific Projects
|
||||
|
||||
Plugins use config files to infer tasks for projects. You can specify which config files are processed by Nx plugins using the `include` and `exclude` properties in the plugin configuration object.
|
||||
|
||||
```jsonc
|
||||
// nx.json
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/jest/plugin",
|
||||
"include": ["packages/**/*"],
|
||||
"exclude": ["**/*-e2e/**/*"],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The `include` and `exclude` properties are file glob patterns that filter which configuration files the plugin processes. In the example above, the `@nx/jest/plugin` will only infer tasks for projects where the `jest.config.ts` file path matches the `packages/**/*` glob but does not match the `**/*-e2e/**/*` glob.
|
||||
|
||||
This is useful when you want a plugin to only affect certain projects, or when you need to apply different plugin options to different sets of projects by registering the same plugin multiple times with different `include`/`exclude` patterns.
|
||||
|
||||
## View Inferred Tasks
|
||||
|
||||
To view the task settings for projects in your workspace, [show the project details](/docs/features/explore-graph) either from the command line or using Nx Console.
|
||||
|
||||
@@ -50,31 +50,3 @@ To see information about the running Nx Daemon (such as its background process I
|
||||
|
||||
The Nx Daemon uses a unix socket to communicate between the daemon and the Nx processes. By default this socket gets placed in a temp directory. If you are using Nx in a docker-compose environment, however, you may want to run the daemon manually
|
||||
and control its location to enable sharing the daemon among your docker containers. To do so, simply set the NX_DAEMON_SOCKET_DIR environment variable to a shared directory.
|
||||
|
||||
## Daemon Behavior in Containers
|
||||
|
||||
Nx automatically disables the daemon in Docker containers and CI environments. The daemon's performance benefits come from maintaining state between commands and watching for file changes—in short-lived environments where each command runs in a fresh container, this state cannot be reused, so the overhead of starting a background process provides no benefit.
|
||||
|
||||
### Automatic Detection
|
||||
|
||||
Nx detects Docker containers by checking for `/.dockerenv` or Docker references in `/proc/self/cgroup`. When detected, the daemon is disabled unless explicitly enabled with `NX_DAEMON=true`.
|
||||
|
||||
### Enabling the Daemon in Containers
|
||||
|
||||
If you have a long-running container with a persistent filesystem (e.g., a dev container), you can enable the daemon:
|
||||
|
||||
```dockerfile
|
||||
ENV NX_DAEMON=true
|
||||
```
|
||||
|
||||
When enabling the daemon in containers, be aware of these considerations:
|
||||
|
||||
- **Volume mounts** can cause inode/mtime changes that interfere with file watching
|
||||
- **Container restarts** invalidate the daemon's socket, requiring a new daemon process
|
||||
- **Permission differences** between the container and host may affect socket communication
|
||||
|
||||
For docker-compose setups with shared daemon sockets, see the [Customizing the socket location](#customizing-the-socket-location) section above.
|
||||
|
||||
{% aside type="note" title="When to enable the daemon" %}
|
||||
Only enable the daemon in containers that persist across multiple Nx commands. For ephemeral CI containers or frequently restarted dev containers, the default (disabled) behavior is more reliable.
|
||||
{% /aside %}
|
||||
|
||||
@@ -143,9 +143,9 @@ The root `tsconfig.base.json` should contain a `compilerOptions` property and no
|
||||
// Required compiler options
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"declarationMap": true
|
||||
// Other options...
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -158,7 +158,7 @@ The root `tsconfig.json` file should extend `tsconfig.base.json` and not include
|
||||
"references": [
|
||||
// UPDATED BY PROJECT GENERATORS
|
||||
// All projects in the repository
|
||||
],
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -174,16 +174,16 @@ Each project's `tsconfig.json` file should extend the `tsconfig.base.json` file
|
||||
// UPDATED BY NX SYNC
|
||||
// All project dependencies
|
||||
{
|
||||
"path": "../utils",
|
||||
"path": "../utils"
|
||||
},
|
||||
// This project's other tsconfig.*.json files
|
||||
{
|
||||
"path": "./tsconfig.lib.json",
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json",
|
||||
},
|
||||
],
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -203,9 +203,9 @@ Each project's `tsconfig.lib.json` file extends the project's `tsconfig.json` fi
|
||||
// UPDATED BY NX SYNC
|
||||
// tsconfig.lib.json files for project dependencies
|
||||
{
|
||||
"path": "../utils/tsconfig.lib.json",
|
||||
},
|
||||
],
|
||||
"path": "../utils/tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -223,9 +223,9 @@ The project's `tsconfig.spec.json` does not need to reference project dependenci
|
||||
"references": [
|
||||
// tsconfig.lib.json for this project
|
||||
{
|
||||
"path": "./tsconfig.lib.json",
|
||||
},
|
||||
],
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -281,10 +281,10 @@ If you define TS path aliases in an individual project's tsconfig files, you sho
|
||||
"#tests/*": ["./tests/*"],
|
||||
"@/icon-name": [
|
||||
"./app/components/ui/icons/name.d.ts",
|
||||
"./types/icon-name.d.ts",
|
||||
],
|
||||
},
|
||||
},
|
||||
"./types/icon-name.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -308,9 +308,9 @@ The paths for each library are defined in the root `tsconfig.base.json` and each
|
||||
"declaration": false,
|
||||
"paths": {
|
||||
// These paths are automatically added by Nx library generators
|
||||
"@myorg/shared-ui": ["packages/shared-ui/src/index.ts"],
|
||||
"@myorg/shared-ui": ["packages/shared-ui/src/index.ts"]
|
||||
// ...
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -31,6 +31,7 @@ filter: 'type:Guides'
|
||||

|
||||
|
||||
7. Add these configuration options
|
||||
|
||||
1. Configure the Identifier **exactly** as `nx-private-cloud`
|
||||
2. For the **Reply URL**, it should point to your Private Cloud instance URL. Make sure it ends with `/auth-callback`
|
||||
|
||||
@@ -45,6 +46,7 @@ filter: 'type:Guides'
|
||||

|
||||
|
||||
10. Configure it as per below
|
||||
|
||||
1. **"Namespace"** needs to be blank
|
||||
2. **"Name:"** needs to be "email"
|
||||
3. See screenshot below. This is an important step, because Nx Cloud will expect the "email" property on each profile that logs in.
|
||||
|
||||
@@ -15,6 +15,7 @@ filter: 'type:Guides'
|
||||

|
||||
|
||||
3. On the Next page, configure it as below:
|
||||
|
||||
1. The Single Sign On URL needs to point to your Nx Cloud instance URL and ends with `/auth-callback`
|
||||
2. The Audience should be `nx-private-cloud`
|
||||
|
||||
@@ -30,6 +31,7 @@ filter: 'type:Guides'
|
||||
|
||||
6. Click “Next”, and select the first option on the next screen.
|
||||
7. Go to the assignments tab and assign the users that can login to the Nx Cloud WebApp:
|
||||
|
||||
1. **Note:** This just gives them permission to use the Nx Cloud web app with their own workspace. Users will still need to be invited manually through the web app to your main workspace.
|
||||
|
||||

|
||||
|
||||
@@ -49,20 +49,20 @@ Conformance rules are configured in the `conformance` property of the `nx.json`
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "scope:shared",
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared"]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"rule": "@nx/conformance/ensure-owners",
|
||||
"projects": ["!experimental-app"],
|
||||
"projects": ["!experimental-app"]
|
||||
},
|
||||
{
|
||||
"rule": "./tools/local-conformance-rule.ts",
|
||||
},
|
||||
],
|
||||
},
|
||||
"rule": "./tools/local-conformance-rule.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ We now have a valid implementation of a rule and we are ready to build it and pu
|
||||
"executor": "@nx/conformance:bundle-rules",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "{projectRoot}/dist",
|
||||
},
|
||||
},
|
||||
},
|
||||
"outputPath": "{projectRoot}/dist"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -67,14 +67,14 @@ Because publishing the rules is a relatively common operation, you can also wire
|
||||
"executor": "@nx/conformance:bundle-rules",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "{projectRoot}/dist",
|
||||
},
|
||||
"outputPath": "{projectRoot}/dist"
|
||||
}
|
||||
},
|
||||
"publish": {
|
||||
"dependsOn": ["build"],
|
||||
"command": "npx nx-cloud publish-conformance-rules {projectRoot}/dist",
|
||||
},
|
||||
},
|
||||
"command": "npx nx-cloud publish-conformance-rules {projectRoot}/dist"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ A sync generator should be able to run without any required options, so update t
|
||||
"title": "",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": [],
|
||||
"required": []
|
||||
}
|
||||
```
|
||||
|
||||
@@ -96,8 +96,8 @@ Global sync generators are registered in the `nx.json` file like this:
|
||||
// nx.json
|
||||
{
|
||||
"sync": {
|
||||
"globalGenerators": ["@myprg/my-plugin:my-sync-generator"],
|
||||
},
|
||||
"globalGenerators": ["@myprg/my-plugin:my-sync-generator"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -169,9 +169,9 @@ For projects using [inferred targets](/docs/concepts/inferred-tasks) (no project
|
||||
{
|
||||
"targets": {
|
||||
"build": {
|
||||
"syncGenerators": ["my-plugin:my-sync-generator"],
|
||||
},
|
||||
},
|
||||
"syncGenerators": ["my-plugin:my-sync-generator"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -183,7 +183,7 @@ You might have to adjust the name of your plugin based on your specific workspac
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"syncGenerators": ["@myorg/my-plugin:my-sync-generator"],
|
||||
"syncGenerators": ["@myorg/my-plugin:my-sync-generator"]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ export interface OldCreateNodesContext extends CreateNodesContextV2 {
|
||||
|
||||
type OldCreateNodes<T = unknown> = readonly [
|
||||
projectFilePattern: string,
|
||||
createNodesFunction: OldCreateNodesFunction<T>,
|
||||
createNodesFunction: OldCreateNodesFunction<T>
|
||||
];
|
||||
|
||||
export type OldCreateNodesFunction<T = unknown> = (
|
||||
|
||||
@@ -111,10 +111,10 @@ Our last step is to add this executor to a given project's `targets` object in y
|
||||
"echo": {
|
||||
"executor": "@my-org/my-plugin:echo",
|
||||
"options": {
|
||||
"textToEcho": "Hello World",
|
||||
},
|
||||
},
|
||||
},
|
||||
"textToEcho": "Hello World"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ Nx provides a utility (`nx list`) that lists both core and community plugins. Yo
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nrwl/nx.git",
|
||||
"directory": "packages/web",
|
||||
},
|
||||
"directory": "packages/web"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -117,98 +117,6 @@ export async function postTasksExecution(options, context) {
|
||||
}
|
||||
```
|
||||
|
||||
## Using `context.argv` to Determine the Command
|
||||
|
||||
The context object includes an `argv` property that contains the original CLI arguments used to invoke Nx. This allows you to distinguish between different execution modes and apply conditional logic.
|
||||
|
||||
### Context Properties
|
||||
|
||||
Both `preTasksExecution` and `postTasksExecution` hooks receive a context object with the following properties:
|
||||
|
||||
```typescript
|
||||
type PreTaskExecutionContext = {
|
||||
id: string;
|
||||
workspaceRoot: string;
|
||||
nxJsonConfiguration: NxJsonConfiguration;
|
||||
argv: string[]; // Original CLI arguments
|
||||
};
|
||||
|
||||
type PostTasksExecutionContext = {
|
||||
id: string;
|
||||
workspaceRoot: string;
|
||||
nxJsonConfiguration: NxJsonConfiguration;
|
||||
taskResults: TaskResults;
|
||||
argv: string[]; // Original CLI arguments
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
};
|
||||
```
|
||||
|
||||
### Example: Detecting Command Types
|
||||
|
||||
```typescript
|
||||
export async function postTasksExecution(options, context) {
|
||||
// Check if running affected command
|
||||
if (context.argv.includes('affected')) {
|
||||
console.log('✅ Ran affected tasks');
|
||||
} else if (context.argv.includes('run-many')) {
|
||||
console.log('✅ Ran tasks for multiple projects');
|
||||
} else {
|
||||
console.log('✅ Ran task for specific project');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example: Conditional Analytics Based on Command
|
||||
|
||||
```typescript
|
||||
function isAffectedCommand(argv) {
|
||||
return argv.includes('affected');
|
||||
}
|
||||
|
||||
function getTargetName(argv) {
|
||||
const targetIndex = argv.findIndex(
|
||||
(arg) => arg === '-t' || arg === '--target'
|
||||
);
|
||||
return targetIndex !== -1 ? argv[targetIndex + 1] : undefined;
|
||||
}
|
||||
|
||||
export async function postTasksExecution(options, context) {
|
||||
const isAffected = isAffectedCommand(context.argv);
|
||||
const target = getTargetName(context.argv);
|
||||
|
||||
// Send analytics with command context
|
||||
await sendAnalytics({
|
||||
executionId: context.id,
|
||||
commandType: isAffected ? 'affected' : 'direct',
|
||||
target: target,
|
||||
taskCount: Object.keys(context.taskResults).length,
|
||||
duration: context.endTime - context.startTime,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Common Command Patterns
|
||||
|
||||
- Direct execution: `nx build my-app` → `argv: ['node', '/path/to/nx', 'build', 'my-app']`
|
||||
- Affected: `nx affected -t build test` → `argv: ['node', '/path/to/nx', 'affected', '-t', 'build', 'test']`
|
||||
- Run many: `nx run-many -t build -p app1 app2` → `argv: ['node', '/path/to/nx', 'run-many', '-t', 'build', '-p', 'app1', 'app2']`
|
||||
|
||||
### Best Practices for Parsing argv
|
||||
|
||||
When working with `context.argv`, parse it defensively:
|
||||
|
||||
```typescript
|
||||
// Bad - assumes structure
|
||||
const target = context.argv[2];
|
||||
|
||||
// Good - searches for the flag
|
||||
const targetIndex = context.argv.findIndex(
|
||||
(arg) => arg === '-t' || arg === '--target'
|
||||
);
|
||||
const target = targetIndex !== -1 ? context.argv[targetIndex + 1] : undefined;
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Keep hooks fast**: Hooks should execute quickly to avoid slowing down the task execution process
|
||||
@@ -216,4 +124,3 @@ const target = targetIndex !== -1 ? context.argv[targetIndex + 1] : undefined;
|
||||
3. **Use environment variables** for configuration that needs to persist across tasks
|
||||
4. **Leverage context data**: Use the context object to access relevant information about the workspace and task results
|
||||
5. **Provide clear errors**: If throwing errors, make sure they are descriptive and actionable
|
||||
6. **Parse argv defensively**: Don't assume the position of arguments; search for specific flags instead
|
||||
|
||||
@@ -39,8 +39,8 @@ First, use your project configuration (in `project.json` or `package.json`) to a
|
||||
{
|
||||
// ... more project configuration here
|
||||
"nx": {
|
||||
"tags": ["scope:client"],
|
||||
},
|
||||
"tags": ["scope:client"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -49,8 +49,8 @@ First, use your project configuration (in `project.json` or `package.json`) to a
|
||||
{
|
||||
// ... more project configuration here
|
||||
"nx": {
|
||||
"tags": ["scope:admin"],
|
||||
},
|
||||
"tags": ["scope:admin"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -59,8 +59,8 @@ First, use your project configuration (in `project.json` or `package.json`) to a
|
||||
{
|
||||
// ... more project configuration here
|
||||
"nx": {
|
||||
"tags": ["scope:shared"],
|
||||
},
|
||||
"tags": ["scope:shared"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -71,7 +71,7 @@ First, use your project configuration (in `project.json` or `package.json`) to a
|
||||
// client/project.json
|
||||
{
|
||||
// ... more project configuration here
|
||||
"tags": ["scope:client"],
|
||||
"tags": ["scope:client"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -79,7 +79,7 @@ First, use your project configuration (in `project.json` or `package.json`) to a
|
||||
// admin/project.json
|
||||
{
|
||||
// ... more project configuration here
|
||||
"tags": ["scope:admin"],
|
||||
"tags": ["scope:admin"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -87,7 +87,7 @@ First, use your project configuration (in `project.json` or `package.json`) to a
|
||||
// utils/project.json
|
||||
{
|
||||
// ... more project configuration here
|
||||
"tags": ["scope:shared"],
|
||||
"tags": ["scope:shared"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -166,19 +166,19 @@ export default [
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "scope:shared",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared"],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:admin",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:client",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:client"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:client"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// ... more ESLint config here
|
||||
}
|
||||
@@ -218,21 +218,21 @@ Configure rules in your `nx.json`:
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "scope:shared",
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared"],
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:admin",
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared", "scope:admin"],
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared", "scope:admin"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:client",
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared", "scope:client"],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"onlyDependOnProjectsWithTags": ["scope:shared", "scope:client"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -261,7 +261,7 @@ Example: projects with any tags (including untagged) can depend on any other pro
|
||||
```jsonc
|
||||
{
|
||||
"sourceTag": "*",
|
||||
"onlyDependOnLibsWithTags": ["*"],
|
||||
"onlyDependOnLibsWithTags": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -272,7 +272,7 @@ Example: projects tagged with `scope:client` can only depend on projects tagged
|
||||
```jsonc
|
||||
{
|
||||
"sourceTag": "scope:client",
|
||||
"onlyDependOnLibsWithTags": ["scope:util"],
|
||||
"onlyDependOnLibsWithTags": ["scope:util"]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -250,19 +250,19 @@ The main downside of this feature is that you have to manually define each proje
|
||||
// UPDATED BY NX SYNC
|
||||
// All project dependencies
|
||||
{
|
||||
"path": "../../packages/product-state",
|
||||
"path": "../../packages/product-state"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/ui/buttons",
|
||||
"path": "../../packages/ui/buttons"
|
||||
},
|
||||
// This project's other tsconfig.*.json files
|
||||
{
|
||||
"path": "./tsconfig.lib.json",
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json",
|
||||
},
|
||||
],
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ Configure Nx Release in your `nx.json` file:
|
||||
// nx.json
|
||||
{
|
||||
"release": {
|
||||
"projects": ["packages/*"],
|
||||
},
|
||||
"projects": ["packages/*"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ Turborepo forces you to manually annotated your non-JavaScript packages, Nx unde
|
||||
Being able to visually explore your workspace is crucial for large monorepos:
|
||||
|
||||
- **Nx**: Rich, interactive visualizer, both locally via the `nx graph` CLI and for every pull request via Nx Cloud. (More [in the docs](/docs/features/explore-graph))
|
||||
- **Turborepo**: [Browser-based graph visualizations](https://turborepo.com/docs/reference/devtools) and [Graphviz image exports](https://turborepo.com/docs/reference/run#--graph-file-name)
|
||||
- **Turborepo**: Basic graphviz image export
|
||||
|
||||
#### IDE/Developer Tools
|
||||
|
||||
|
||||
+5
-5
@@ -14,8 +14,8 @@ Specifying which tags a project is allowed to depend on can sometimes lead to a
|
||||
"scope:shared",
|
||||
"scope:utils",
|
||||
"scope:core",
|
||||
"scope:client",
|
||||
],
|
||||
"scope:client"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -25,7 +25,7 @@ The property `notDependOnLibsWithTags` is used to invert this condition by expli
|
||||
{
|
||||
"sourceTag": "scope:client",
|
||||
// we accept any tag except for `scope:admin`
|
||||
"notDependOnLibsWithTags": ["scope:admin"],
|
||||
"notDependOnLibsWithTags": ["scope:admin"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -38,9 +38,9 @@ In contrast to `onlyDependOnLibsWithTags`, the `notDependOnLibsWithTags` will al
|
||||
"type:react",
|
||||
"type:utils",
|
||||
"type:animation",
|
||||
"type:model",
|
||||
"type:model"
|
||||
],
|
||||
// make sure no `angular` code ends up being referenced by react projects
|
||||
"notDependOnLibsWithTags": ["type:angular"],
|
||||
"notDependOnLibsWithTags": ["type:angular"]
|
||||
}
|
||||
```
|
||||
|
||||
+18
-18
@@ -66,16 +66,16 @@ export default [
|
||||
// projects tagged with "frontend" can't import from "@nestjs/common"
|
||||
{
|
||||
"sourceTag": "frontend",
|
||||
"bannedExternalImports": ["@nestjs/common"],
|
||||
"bannedExternalImports": ["@nestjs/common"]
|
||||
},
|
||||
// projects tagged with "backend" can't import from "@angular/core"
|
||||
{
|
||||
"sourceTag": "backend",
|
||||
"bannedExternalImports": ["@angular/core"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"bannedExternalImports": ["@angular/core"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// ... more ESLint config here
|
||||
}
|
||||
@@ -136,11 +136,11 @@ export default [
|
||||
// projects tagged with "type:util" can't import from "react" or related projects
|
||||
{
|
||||
"sourceTag": "type:util",
|
||||
"bannedExternalImports": ["*react*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"bannedExternalImports": ["*react*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// ... more ESLint config here
|
||||
}
|
||||
@@ -220,24 +220,24 @@ export default [
|
||||
// projects tagged with "type:util" can only import from "date-fns"
|
||||
{
|
||||
"sourceTag": "type:util",
|
||||
"allowedExternalImports": ["date-fns"],
|
||||
"allowedExternalImports": ["date-fns"]
|
||||
},
|
||||
// ui libraries clean from data access concerns
|
||||
// projects tagged with "type:ui" can only import packages matching "@angular/*" except "@angular/common/http"
|
||||
{
|
||||
"sourceTag": "type:ui",
|
||||
"allowedExternalImports": ["@angular/*"],
|
||||
"bannedExternalImports": ["@angular/common/http"],
|
||||
"bannedExternalImports": ["@angular/common/http"]
|
||||
},
|
||||
// keeping the domain logic clean from infrastructure concerns
|
||||
// projects tagged with "type:core" can't import any external packages.
|
||||
{
|
||||
"sourceTag": "type:core",
|
||||
"allowedExternalImports": [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"allowedExternalImports": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+26
-26
@@ -16,7 +16,7 @@ Our project configurations might now look like this:
|
||||
{
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:client", "type:app"],
|
||||
"tags": ["scope:client", "type:app"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -25,7 +25,7 @@ Our project configurations might now look like this:
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:client", "type:app"],
|
||||
"implicitDependencies": ["client"],
|
||||
"implicitDependencies": ["client"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@ Our project configurations might now look like this:
|
||||
{
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:admin", "type:app"],
|
||||
"tags": ["scope:admin", "type:app"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -42,7 +42,7 @@ Our project configurations might now look like this:
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:admin", "type:app"],
|
||||
"implicitDependencies": ["admin"],
|
||||
"implicitDependencies": ["admin"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -50,7 +50,7 @@ Our project configurations might now look like this:
|
||||
{
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:client", "type:feature"],
|
||||
"tags": ["scope:client", "type:feature"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -58,7 +58,7 @@ Our project configurations might now look like this:
|
||||
{
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:admin", "type:feature"],
|
||||
"tags": ["scope:admin", "type:feature"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -66,7 +66,7 @@ Our project configurations might now look like this:
|
||||
{
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:shared", "type:ui"],
|
||||
"tags": ["scope:shared", "type:ui"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -74,7 +74,7 @@ Our project configurations might now look like this:
|
||||
{
|
||||
// ... more project configuration here
|
||||
|
||||
"tags": ["scope:shared", "type:util"],
|
||||
"tags": ["scope:shared", "type:util"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -162,35 +162,35 @@ export default [
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "scope:shared",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared"],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:admin",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:client",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:client"],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:client"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:app",
|
||||
"onlyDependOnLibsWithTags": ["type:feature", "type:ui", "type:util"],
|
||||
"onlyDependOnLibsWithTags": ["type:feature", "type:ui", "type:util"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:feature",
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"],
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:ui",
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"],
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:util",
|
||||
"onlyDependOnLibsWithTags": ["type:util"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"onlyDependOnLibsWithTags": ["type:util"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// ... more ESLint config here
|
||||
}
|
||||
@@ -267,22 +267,22 @@ export default [
|
||||
{
|
||||
// this constraint applies to all "admin" projects
|
||||
"sourceTag": "scope:admin",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"],
|
||||
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:ui",
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"],
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"]
|
||||
},
|
||||
{
|
||||
// we don't want our admin ui components to depend on anything except utilities,
|
||||
// and we also want to ban router imports
|
||||
"allSourceTags": ["scope:admin", "type:ui"],
|
||||
"onlyDependOnLibsWithTags": ["type:util"],
|
||||
"bannedExternalImports": ["*router*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"bannedExternalImports": ["*router*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// ... more ESLint config here
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ An API token is a secure credential that allows scripts and other processes to a
|
||||
- `write:pullrequest:bitbucket` - to write comments on pull requests
|
||||
- `read:repository:bitbucket` - to read repository contents
|
||||
- `write:repository:bitbucket` - to write files to the repository
|
||||
- `read:user:bitbucket` - verify username from email address
|
||||
- `account:read` - verify username from email address
|
||||
|
||||

|
||||
|
||||
6. Click "Create token" and copy your newly created API token
|
||||
|
||||
|
||||
@@ -82,13 +82,15 @@ Nx writes resource metrics to a local directory during task execution. To view t
|
||||
|
||||
### Configuration
|
||||
|
||||
Metrics collection is currently on by default for enterprise users with Nx version 22.1 or higher. To disable it, set the `NX_CLOUD_DISABLE_METRICS_COLLECTION` environment variable:
|
||||
Metrics collection is currently opt-in. To enable it, set the `NX_CLOUD_ENABLE_METRICS_COLLECTION` environment variable:
|
||||
|
||||
```shell
|
||||
export NX_CLOUD_DISABLE_METRICS_COLLECTION=true
|
||||
export NX_CLOUD_ENABLE_METRICS_COLLECTION=true
|
||||
```
|
||||
|
||||
Metrics are written to the local Nx cache directory by default (`.nx/cache/metrics` unless manually overridden). You can change this directory by setting the `NX_CLOUD_METRICS_DIRECTORY` environment variable.
|
||||
In future Nx versions, metrics collection will be enabled by default. You can use this same variable to disable it if needed.
|
||||
|
||||
Set the `NX_CLOUD_METRICS_DIRECTORY` environment variable to a directory for the metrics to be written in e.g. `.nx/cache/metrics`.
|
||||
|
||||
```shell
|
||||
export NX_CLOUD_METRICS_DIRECTORY=/path/to/metrics
|
||||
@@ -96,7 +98,7 @@ export NX_CLOUD_METRICS_DIRECTORY=/path/to/metrics
|
||||
|
||||
### Saving Metrics as CI Artifacts
|
||||
|
||||
Set up your CI to save the metrics directory as an artifact so you can download it later. The following examples assume that the default cache directory (`.nx/cache/metrics`) is used. If you overwrite the metrics directory, adjust the paths in the artifact upload step accordingly.
|
||||
Set up your CI to save the metrics directory as an artifact so you can download it later.
|
||||
|
||||
{% tabs syncKey="ci-provider" %}
|
||||
{% tabitem label="GitHub Actions" %}
|
||||
@@ -106,6 +108,9 @@ Set up your CI to save the metrics directory as an artifact so you can download
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NX_CLOUD_ENABLE_METRICS_COLLECTION: true
|
||||
NX_CLOUD_METRICS_DIRECTORY: ${{ github.workspace }}/.nx/cache/metrics
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
@@ -125,6 +130,9 @@ jobs:
|
||||
```yaml
|
||||
# .gitlab-ci.yml
|
||||
build:
|
||||
variables:
|
||||
NX_CLOUD_ENABLE_METRICS_COLLECTION: 'true'
|
||||
NX_CLOUD_METRICS_DIRECTORY: $CI_PROJECT_DIR/.nx/cache/metrics
|
||||
script:
|
||||
- npm ci
|
||||
- npx nx affected -t build test lint
|
||||
@@ -143,6 +151,9 @@ jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: cimg/node:lts
|
||||
environment:
|
||||
NX_CLOUD_ENABLE_METRICS_COLLECTION: true
|
||||
NX_CLOUD_METRICS_DIRECTORY: /home/circleci/project/.nx/cache/metrics
|
||||
steps:
|
||||
- checkout
|
||||
- run: npm ci
|
||||
|
||||
@@ -40,6 +40,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
name: Checkout [Pull Request]
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
# We need to fetch all branches and commits so that Nx affected has a base to compare against.
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
name: Checkout [Default Branch]
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
with:
|
||||
# We need to fetch all branches and commits so that Nx affected has a base to compare against.
|
||||
fetch-depth: 0
|
||||
@@ -192,7 +202,7 @@ jobs:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: '0'
|
||||
fetchDepth: 0
|
||||
fetchFilter: tree:0
|
||||
persistCredentials: true
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ jobs:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: '0'
|
||||
fetchDepth: 0
|
||||
fetchFilter: tree:0
|
||||
# Set Azure Devops CLI default settings
|
||||
- bash: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject)
|
||||
|
||||
@@ -21,4 +21,4 @@ In addition to viewing the Project Details View, Codelenses in tooling configura
|
||||
If you would like to disable the Codelens feature, you can do so easily:
|
||||
|
||||
- In VSCode, simply turn off the `nxConsole.enableCodeLens` setting
|
||||
- In JetBrains IDEs, right-click a Codelens and select ``Hide `Code Vision: Nx Config Files` Inlay Hints ``
|
||||
- In JetBrains IDEs, right-click a Codelens and select `` Hide `Code Vision: Nx Config Files` Inlay Hints ``
|
||||
|
||||
@@ -29,10 +29,10 @@ To enable GitHub release creation for your workspace, set `release.changelog.wor
|
||||
"release": {
|
||||
"changelog": {
|
||||
"workspaceChangelog": {
|
||||
"createRelease": "github",
|
||||
},
|
||||
},
|
||||
},
|
||||
"createRelease": "github"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,10 +51,10 @@ Since GitHub releases contain the changelog, you may wish to disable the generat
|
||||
"changelog": {
|
||||
"workspaceChangelog": {
|
||||
"file": false,
|
||||
"createRelease": "github",
|
||||
},
|
||||
},
|
||||
},
|
||||
"createRelease": "github"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -70,10 +70,10 @@ Nx Release supports creating GitHub releases for project level changelogs as wel
|
||||
"release": {
|
||||
"changelog": {
|
||||
"projectChangelogs": {
|
||||
"createRelease": "github",
|
||||
},
|
||||
},
|
||||
},
|
||||
"createRelease": "github"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -93,10 +93,10 @@ If you are not using github.com, and instead using a self-hosted GitHub Enterpri
|
||||
"workspaceChangelog": {
|
||||
"createRelease": {
|
||||
"provider": "github-enterprise-server",
|
||||
"hostname": "github.example.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"hostname": "github.example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -29,10 +29,10 @@ To enable GitLab release creation for your workspace, set `release.changelog.wor
|
||||
"release": {
|
||||
"changelog": {
|
||||
"workspaceChangelog": {
|
||||
"createRelease": "gitlab",
|
||||
},
|
||||
},
|
||||
},
|
||||
"createRelease": "gitlab"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,10 +51,10 @@ Since GitLab releases contain the changelog, you may wish to disable the generat
|
||||
"changelog": {
|
||||
"workspaceChangelog": {
|
||||
"file": false,
|
||||
"createRelease": "gitlab",
|
||||
},
|
||||
},
|
||||
},
|
||||
"createRelease": "gitlab"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -70,10 +70,10 @@ Nx Release supports creating GitLab releases for project level changelogs as wel
|
||||
"release": {
|
||||
"changelog": {
|
||||
"projectChangelogs": {
|
||||
"createRelease": "gitlab",
|
||||
},
|
||||
},
|
||||
},
|
||||
"createRelease": "gitlab"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -93,10 +93,10 @@ If you are not using gitlab.com, and are instead using a self-hosted GitLab inst
|
||||
"workspaceChangelog": {
|
||||
"createRelease": {
|
||||
"provider": "gitlab",
|
||||
"hostname": "gitlab.example.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"hostname": "gitlab.example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -48,9 +48,9 @@ In order to ensure that images are built before versioning, use the `preVersionC
|
||||
{
|
||||
"release": {
|
||||
"docker": {
|
||||
"preVersionCommand": "npx nx run-many -t docker:build",
|
||||
},
|
||||
},
|
||||
"preVersionCommand": "npx nx run-many -t docker:build"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -66,11 +66,11 @@ When using release groups with Docker, use the `groupPreVersionCommand` option t
|
||||
"my-group": {
|
||||
"projects": ["api", "microservice"],
|
||||
"docker": {
|
||||
"groupPreVersionCommand": "npx nx run-many -t docker:build -p api,microservice",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"groupPreVersionCommand": "npx nx run-many -t docker:build -p api,microservice"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -71,9 +71,9 @@ To set the versionPrefix option globally or for a specific project, add it to ei
|
||||
{
|
||||
"release": {
|
||||
"version": {
|
||||
"versionPrefix": "^", // or "", "~", "^", "=" depending on your preference
|
||||
},
|
||||
},
|
||||
"versionPrefix": "^" // or "", "~", "^", "=" depending on your preference
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -103,10 +103,10 @@ For complete control over changelog formatting, you can provide a custom changel
|
||||
"release": {
|
||||
"changelog": {
|
||||
"projectChangelogs": {
|
||||
"renderer": "./tools/custom-changelog-renderer.ts",
|
||||
},
|
||||
},
|
||||
},
|
||||
"renderer": "./tools/custom-changelog-renderer.ts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+5
-32
@@ -21,11 +21,11 @@ To enable version plans as a feature in your workspace, set `release.versionPlan
|
||||
// nx.json
|
||||
{
|
||||
"release": {
|
||||
"versionPlans": true,
|
||||
"versionPlans": true
|
||||
// other release config such as projects to include in releases etc
|
||||
// projects: ["packages/**/*"]
|
||||
// ...
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -164,39 +164,12 @@ By default, all files that have changed are considered, but you may not want all
|
||||
{
|
||||
"release": {
|
||||
"versionPlans": {
|
||||
"ignorePatternsForPlanCheck": ["**/*.spec.ts"],
|
||||
},
|
||||
},
|
||||
"ignorePatternsForPlanCheck": ["**/*.spec.ts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% aside type="caution" title="Important: Pattern Syntax" %}
|
||||
|
||||
The `ignorePatternsForPlanCheck` patterns follow [gitignore semantics](https://git-scm.com/docs/gitignore). When using negation patterns (patterns starting with `!`) to "un-ignore" certain files, be aware that:
|
||||
|
||||
**Working patterns:**
|
||||
|
||||
- `["**/*.spec.ts"]` - ignore all spec files
|
||||
- `["**/*.ts", "!**/src/**"]` - ignore all .ts files except those in src/ directories
|
||||
|
||||
**Non-working patterns:**
|
||||
|
||||
- `["*", "!src/"]` - this does NOT work as expected because `*` in gitignore matches at the root level and negation patterns cannot properly un-ignore nested paths
|
||||
|
||||
If you want to ignore all files except those in specific directories, use file extension patterns instead of wildcards:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"release": {
|
||||
"versionPlans": {
|
||||
"ignorePatternsForPlanCheck": ["**/*.ts", "**/*.json", "!**/src/**"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
{% /aside %}
|
||||
|
||||
To see more details about the changed files that were detected and the filtering logic that was used to determine the ultimately changed projects behind the scenes, you can pass `--verbose` to the command:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -35,6 +35,7 @@ If you apply project or group filtering to the programmatic API via the `project
|
||||
- `workspaceVersion`: The new overall version of the workspace. This is only applicable in cases where all projects are versioned together in a single release group. In all other cases, this will be `null`.
|
||||
|
||||
- `projectsVersionData`: A map of project names to their version data. The version data is a `VersionData` object, which contains the following properties:
|
||||
|
||||
- `currentVersion`: The current version of the project. This is the version that the project was at before the versioning process began.
|
||||
- `newVersion`: The new version of the project.
|
||||
- `dockerVersion`: The new version of the project if it is a docker project.
|
||||
@@ -63,6 +64,7 @@ console.log(releaseGraph);
|
||||
`releaseChangelog` will return a `NxReleaseChangelogResult` object containing the following properties:
|
||||
|
||||
- `workspaceChangelog`: The changelog data for the workspace, if applicable based on the nx release config.
|
||||
|
||||
- `releaseVersion`: Relevant version data for the new changelog entry.
|
||||
- `contents`: The changelog entry contents.
|
||||
|
||||
|
||||
@@ -361,9 +361,9 @@ Configure alternative registries in your `nx.json`:
|
||||
{
|
||||
"release": {
|
||||
"docker": {
|
||||
"registryUrl": "ghcr.io", // GitHub Container Registry
|
||||
},
|
||||
},
|
||||
"registryUrl": "ghcr.io" // GitHub Container Registry
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -49,9 +49,9 @@ For example, to release just the projects in the `crates` directory:
|
||||
"projects": ["crates/*"],
|
||||
"version": {
|
||||
// Legacy versioning is currently required for the @monodon/rust plugin, see the note above for more details
|
||||
"useLegacyVersioning": true,
|
||||
},
|
||||
},
|
||||
"useLegacyVersioning": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ To learn more about release groups, see the [Release Groups](/docs/guides/nx-rel
|
||||
{
|
||||
"release": {
|
||||
"releaseTag": {
|
||||
"pattern": "release/{projectName}/{version}",
|
||||
"pattern": "release/{projectName}/{version}"
|
||||
},
|
||||
"groups": {
|
||||
"apps": {
|
||||
@@ -91,14 +91,14 @@ To learn more about release groups, see the [Release Groups](/docs/guides/nx-rel
|
||||
// `docker.io` is the default so you could leave this out for Docker Hub.
|
||||
"registryUrl": "docker.io",
|
||||
// The pre-version command is run before versioning, useful for verifying the Docker image.
|
||||
"groupPreVersionCommand": "echo BEFORE VERSIONING",
|
||||
"groupPreVersionCommand": "echo BEFORE VERSIONING"
|
||||
},
|
||||
"changelog": {
|
||||
"projectChangelogs": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"projectChangelogs": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -122,14 +122,14 @@ To learn more about release groups, see the [Release Groups](/docs/guides/nx-rel
|
||||
// `docker.io` is the default so you could leave this out for Docker Hub.
|
||||
"registryUrl": "docker.io",
|
||||
// The pre-version command is run before versioning, useful for verifying the Docker image.
|
||||
"groupPreVersionCommand": "echo BEFORE VERSIONING",
|
||||
"groupPreVersionCommand": "echo BEFORE VERSIONING"
|
||||
},
|
||||
"changelog": {
|
||||
"projectChangelogs": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"projectChangelogs": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@ To create release groups, define them in your `nx.json` file under the `release.
|
||||
"groups": {
|
||||
"backend": {
|
||||
"projects": ["api", "auth-service", "payment-service"],
|
||||
"projectsRelationship": "fixed",
|
||||
"projectsRelationship": "fixed"
|
||||
},
|
||||
"frontend": {
|
||||
"projects": ["web-app", "mobile-app"],
|
||||
"projectsRelationship": "independent",
|
||||
},
|
||||
},
|
||||
},
|
||||
"projectsRelationship": "independent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -80,11 +80,11 @@ When `projectsRelationship` is set to `"fixed"` (the default):
|
||||
"shared-libraries": {
|
||||
"projects": ["ui-components", "utils", "data-access"],
|
||||
// this is also the default and can be omitted
|
||||
"projectsRelationship": "fixed",
|
||||
"projectsRelationship": "fixed"
|
||||
// ... other group configuration options ...
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -103,11 +103,11 @@ When `projectsRelationship` is set to `"independent"`:
|
||||
"groups": {
|
||||
"microservices": {
|
||||
"projects": ["user-service", "order-service", "inventory-service"],
|
||||
"projectsRelationship": "independent",
|
||||
"projectsRelationship": "independent"
|
||||
// ... other group configuration options ...
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -125,7 +125,7 @@ Customize versioning behavior per group:
|
||||
"version": {
|
||||
"conventionalCommits": false,
|
||||
"versionPrefix": "~",
|
||||
"updateDependents": "always",
|
||||
"updateDependents": "always"
|
||||
},
|
||||
"groups": {
|
||||
"npm-packages": {
|
||||
@@ -135,11 +135,11 @@ Customize versioning behavior per group:
|
||||
//configuration for this specific group
|
||||
"conventionalCommits": true,
|
||||
"versionPrefix": "^",
|
||||
"updateDependents": "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"updateDependents": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -152,9 +152,9 @@ Configure changelog generation per group:
|
||||
"release": {
|
||||
"changelog": {
|
||||
"projectChangelogs": {
|
||||
"file": false,
|
||||
"file": false
|
||||
// ... other changelog configuration options ...
|
||||
},
|
||||
}
|
||||
},
|
||||
"groups": {
|
||||
"public-apis": {
|
||||
@@ -163,11 +163,11 @@ Configure changelog generation per group:
|
||||
"changelog": {
|
||||
"file": "{projectRoot}/CHANGELOG.md",
|
||||
"createRelease": "github",
|
||||
"renderer": "@my-org/custom-changelog-renderer",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"renderer": "@my-org/custom-changelog-renderer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -183,17 +183,17 @@ Customize how relevant git tags should be discovered and created for each group
|
||||
"projects": ["backend-*"],
|
||||
"releaseTag": {
|
||||
"pattern": "backend-{version}",
|
||||
"requireSemver": true,
|
||||
},
|
||||
"requireSemver": true
|
||||
}
|
||||
},
|
||||
"frontend": {
|
||||
"projects": ["frontend-*"],
|
||||
"releaseTag": {
|
||||
"pattern": "frontend-{version}",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"pattern": "frontend-{version}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -209,15 +209,15 @@ For independently versioned projects, regardless of whether they are in the same
|
||||
"group1": {
|
||||
// project-a depends on project-b, even though it
|
||||
// happens to be in a different release group here
|
||||
"projects": ["project-a"],
|
||||
"projects": ["project-a"]
|
||||
},
|
||||
"group2": {
|
||||
// project-a depends on project-b, even though it
|
||||
// happens to be in a different release group here
|
||||
"projects": ["project-b"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"projects": ["project-b"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -237,14 +237,14 @@ You can have different relationship types for different groups in the same works
|
||||
"groups": {
|
||||
"platform": {
|
||||
"projects": ["core", "common", "shared"],
|
||||
"projectsRelationship": "fixed",
|
||||
"projectsRelationship": "fixed"
|
||||
},
|
||||
"applications": {
|
||||
"projects": ["app-*"],
|
||||
"projectsRelationship": "independent",
|
||||
},
|
||||
},
|
||||
},
|
||||
"projectsRelationship": "independent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -259,17 +259,17 @@ Run different build or preparation commands for each group:
|
||||
"compiled-packages": {
|
||||
"projects": ["lib-*"],
|
||||
"version": {
|
||||
"groupPreVersionCommand": "nx run-many -t build --projects=...",
|
||||
},
|
||||
"groupPreVersionCommand": "nx run-many -t build --projects=..."
|
||||
}
|
||||
},
|
||||
"documentation": {
|
||||
"projects": ["docs-*"],
|
||||
"version": {
|
||||
"groupPreVersionCommand": "nx run-many -t generate-docs --projects=...",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"groupPreVersionCommand": "nx run-many -t generate-docs --projects=..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -283,15 +283,15 @@ When using [version plans](/docs/guides/nx-release/file-based-versioning-version
|
||||
"groups": {
|
||||
"backend": {
|
||||
"projects": ["api-*"],
|
||||
"versionPlans": true,
|
||||
"versionPlans": true
|
||||
},
|
||||
"frontend": {
|
||||
"projects": ["ui-*"],
|
||||
"projects": ["ui-*"]
|
||||
// version plans is not enabled here and
|
||||
// it's not set at the root level either
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -96,10 +96,10 @@ If, for example, we want to build our projects to a centralized `dist/` director
|
||||
// We use the object form of the manifestRootsToUpdate to specify that we want to update the dist package.json files and not preserve the local dependency references (if not using pnpm or bun)
|
||||
{
|
||||
"path": "dist/packages/{projectName}",
|
||||
"preserveLocalDependencyProtocols": false, // (NOT NEEDED WHEN USING pnpm or bun) because we need to ensure our dist package.json files are valid for publishing and the local dependency references such as "workspace:" and "file:" are removed
|
||||
},
|
||||
],
|
||||
},
|
||||
"preserveLocalDependencyProtocols": false // (NOT NEEDED WHEN USING pnpm or bun) because we need to ensure our dist package.json files are valid for publishing and the local dependency references such as "workspace:" and "file:" are removed
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"targetDefaults": {
|
||||
// Ensure that publishing works from the dist directory
|
||||
@@ -107,10 +107,10 @@ If, for example, we want to build our projects to a centralized `dist/` director
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
// the packageRoot property is specific the TS/JS nx-release-publish implementation, other ecosystem plugins may have different options
|
||||
"packageRoot": "dist/packages/{projectName}", // path structure for your dist directory, where {projectRoot} and {projectName} are available placeholders that will be interpolated by Nx
|
||||
},
|
||||
},
|
||||
},
|
||||
"packageRoot": "dist/packages/{projectName}" // path structure for your dist directory, where {projectRoot} and {projectName} are available placeholders that will be interpolated by Nx
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -131,8 +131,8 @@ For example, using our packages from Scenario 1 above, if we want to reference t
|
||||
{
|
||||
"name": "my-project", // note there is no version number in the source package.json file because it will never be updated
|
||||
"dependencies": {
|
||||
"my-other-project-in-the-monorepo": "workspace:*", // or "file:../my-other-project-in-the-monorepo", depending on your preference and which package manager you are using
|
||||
},
|
||||
"my-other-project-in-the-monorepo": "workspace:*" // or "file:../my-other-project-in-the-monorepo", depending on your preference and which package manager you are using
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -146,18 +146,18 @@ If the package manager we are using is not using pnpm or bun (See Scenario 4 bel
|
||||
"version": {
|
||||
"manifestRootsToUpdate": ["dist/packages/{projectName}"], // path structure for your dist directory, where {projectRoot} and {projectName} are available placeholders that will be interpolated by Nx
|
||||
"currentVersionResolver": "git-tag", // or "registry", because we are no longer referencing our source package.json as the source of truth for the current version
|
||||
"preserveLocalDependencyProtocols": false, // (NOT NEEDED WHEN USING pnpm or bun) because we need to ensure our dist package.json files are valid for publishing and the local dependency references are removed
|
||||
},
|
||||
"preserveLocalDependencyProtocols": false // (NOT NEEDED WHEN USING pnpm or bun) because we need to ensure our dist package.json files are valid for publishing and the local dependency references are removed
|
||||
}
|
||||
},
|
||||
"targetDefaults": {
|
||||
// Ensure that publishing works from the dist directory
|
||||
// The nx-release-publish target is added implicitly behind the scenes by Nx Release, and we can therefore configure it in targetDefaults
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/packages/{projectName}", // path structure for your dist directory, where {projectRoot} and {projectName} are available placeholders that will be interpolated by Nx
|
||||
},
|
||||
},
|
||||
},
|
||||
"packageRoot": "dist/packages/{projectName}" // path structure for your dist directory, where {projectRoot} and {projectName} are available placeholders that will be interpolated by Nx
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -169,8 +169,8 @@ After applying a patch version, our dist package.json will therefore ultimately
|
||||
"name": "my-project",
|
||||
"version": "0.1.2", // the version number is applied
|
||||
"dependencies": {
|
||||
"my-other-project-in-the-monorepo": "0.1.2", // the dependency reference is updated from the workspace reference to the actual version number (if not using pnpm or bun)
|
||||
},
|
||||
"my-other-project-in-the-monorepo": "0.1.2" // the dependency reference is updated from the workspace reference to the actual version number (if not using pnpm or bun)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -196,8 +196,8 @@ For example, using this source package.json file, when applying a patch release:
|
||||
"name": "my-project",
|
||||
"version": "0.1.2",
|
||||
"dependencies": {
|
||||
"my-other-project-in-the-monorepo": "workspace:*",
|
||||
},
|
||||
"my-other-project-in-the-monorepo": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -210,8 +210,8 @@ Nx release will see this and update the "version" number to `0.1.3`, and leave t
|
||||
"version": "0.1.3", // our version number is updated as expected
|
||||
"dependencies": {
|
||||
// our workspace dependency reference is preserved
|
||||
"my-other-project-in-the-monorepo": "workspace:*",
|
||||
},
|
||||
"my-other-project-in-the-monorepo": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -340,9 +340,9 @@ As you configure `inputs`, keep the project details screen open and it will refr
|
||||
{
|
||||
"targetDefaults": {
|
||||
"build": {
|
||||
"inputs": ["production", "^production"],
|
||||
},
|
||||
},
|
||||
"inputs": ["production", "^production"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -364,9 +364,9 @@ Defining `inputs` of a target in `project.json` or `package.json` will apply onl
|
||||
"name": "myreactapp",
|
||||
"targets": {
|
||||
"build": {
|
||||
"inputs": ["production", "^production"],
|
||||
},
|
||||
},
|
||||
"inputs": ["production", "^production"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -432,9 +432,9 @@ Given the above configurations, exclude the test and config files from the `prod
|
||||
"production": [
|
||||
"default",
|
||||
"!{projectRoot}/jest.config.ts",
|
||||
"!{projectRoot}/**/?(*.)+(spec|test).ts",
|
||||
],
|
||||
},
|
||||
"!{projectRoot}/**/?(*.)+(spec|test).ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -455,7 +455,7 @@ For example, to consider the version of Node.js in the hash of every task, add `
|
||||
{
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*", "sharedGlobals"],
|
||||
"sharedGlobals": [{ "runtime": "node --version" }],
|
||||
},
|
||||
"sharedGlobals": [{ "runtime": "node --version" }]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -80,9 +80,9 @@ As you configure `outputs`, keep the project details screen open and it will ref
|
||||
{
|
||||
"targetDefaults": {
|
||||
"build": {
|
||||
"outputs": ["{projectRoot}/dist"],
|
||||
},
|
||||
},
|
||||
"outputs": ["{projectRoot}/dist"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -108,9 +108,9 @@ Defining `outputs` of a target in `project.json` or `package.json` will apply on
|
||||
"name": "myreactapp",
|
||||
"targets": {
|
||||
"build": {
|
||||
"outputs": ["{projectRoot}/dist"],
|
||||
},
|
||||
},
|
||||
"outputs": ["{projectRoot}/dist"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -77,13 +77,13 @@ Our fully configured example would look like this:
|
||||
// generates docs from source code of all dependencies
|
||||
"inputs": ["^production"],
|
||||
// the docs site is created under /docs
|
||||
"outputs": ["{workspaceRoot}/docs"],
|
||||
},
|
||||
},
|
||||
"outputs": ["{workspaceRoot}/docs"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"docs": "node ./generateDocsSite.js",
|
||||
},
|
||||
"docs": "node ./generateDocsSite.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ To skip caching for a specific task, use the `--skip-nx-cache` flag. This can be
|
||||
npx nx build --skip-nx-cache
|
||||
```
|
||||
|
||||
This will avoid using any local or remote cache. If using Nx Cloud, the run will not be recorded either.
|
||||
This will avoid using any local or remote cache.
|
||||
|
||||
## Skip Remote Caching from Nx Cloud
|
||||
|
||||
@@ -24,7 +24,7 @@ To skip remote caching provided by Nx Cloud, use the `--no-cloud` flag. This ens
|
||||
npx nx build --no-cloud
|
||||
```
|
||||
|
||||
It will **still use the local cache if available**. If using Nx Cloud the run will not be recorded either.
|
||||
It will **still use the local cache if available**.
|
||||
|
||||
## Reset
|
||||
|
||||
|
||||
@@ -18,12 +18,7 @@ The initial Nx 21 release disables the Terminal UI on Windows. We are currently
|
||||
|
||||
If your terminal and environment are supported then the Terminal UI will be enabled by default when you run any tasks with `nx run`/`nx run-many`/`nx affected` in Nx v21 and later. The Terminal UI will not be used in CI environments.
|
||||
|
||||
To manually control the Terminal UI, you can:
|
||||
|
||||
- Use the `--no-tui` flag when running commands: `nx run-many -t build --no-tui`
|
||||
- Use the `--tui` flag to explicitly enable it: `nx run-many -t build --tui`
|
||||
- Set `NX_TUI=false` in your environment variables
|
||||
- Set `tui.enabled` to `false` in your `nx.json` configuration file
|
||||
If you want to manually disable the Terminal UI, you can set `NX_TUI=false` in your environment variables, or set `tui.enabled` to `false` in your `nx.json` configuration file.
|
||||
|
||||
```json
|
||||
// nx.json
|
||||
|
||||
@@ -214,18 +214,18 @@ If you don't have the command and need to find out from which version to run the
|
||||
"version": "16.1.0-beta.1",
|
||||
"x-prompt": "Do you want to update the Angular version to v16?",
|
||||
"requires": {
|
||||
"@angular/core": ">=15.2.0 <16.0.0",
|
||||
"@angular/core": ">=15.2.0 <16.0.0"
|
||||
},
|
||||
"packages": {
|
||||
"@angular/core": {
|
||||
"version": "~16.0.0",
|
||||
"alwaysAddToPackageJson": true,
|
||||
},
|
||||
"alwaysAddToPackageJson": true
|
||||
}
|
||||
// ...
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
// ...
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -117,10 +117,10 @@ In order to have Nx actually use the `.env.build.development` environment variab
|
||||
"build": {
|
||||
// ...
|
||||
"configurations": {
|
||||
"development": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
"development": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ This command will update `.yarnrc.yml` with the path to the local yarn `bin` of
|
||||
// package.json
|
||||
{
|
||||
// ...
|
||||
"packageManager": "yarn@3.6.1",
|
||||
"packageManager": "yarn@3.6.1"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -88,10 +88,10 @@ Use `npx nx-cloud record --` to capture the logs for `nx conformance:check` in t
|
||||
* The projects array allows users to opt in or out of violations for specific projects being reported by the current rule.
|
||||
* The array can contain any valid matchers for findMatchingProjects(), by default the implied value is ["*"]. (Optional)
|
||||
*/
|
||||
"projects": ["*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"projects": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ The new style looks like this:
|
||||
{
|
||||
"targets": {
|
||||
"build": {
|
||||
"inputs": ["^build", { "runtime": "node -v" }],
|
||||
"inputs": ["^build", { "runtime": "node -v" }]
|
||||
// ...
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -141,6 +141,7 @@ A Project Graph Processor takes a project graph and returns a new project graph.
|
||||
Plugins should export a function named `processProjectGraph` that handles updating the project graph with new nodes and edges. This function receives two things:
|
||||
|
||||
- A `ProjectGraph`
|
||||
|
||||
- `graph.nodes` lists all the projects currently known to Nx.
|
||||
- `graph.dependencies` lists the dependencies between projects.
|
||||
|
||||
|
||||
@@ -30,6 +30,6 @@ nx generate @nx/plugin:executor tools/my-plugin/src/executors/my-executor
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"executor": "@my-org/my-plugin:my-executor",
|
||||
"executor": "@my-org/my-plugin:my-executor"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -33,10 +33,10 @@ After this command, `workspace.json` should look like this:
|
||||
"version": 2,
|
||||
"projects": {
|
||||
"my-app": "apps/my-app",
|
||||
"some-lib": "libs/some-lib",
|
||||
"some-lib": "libs/some-lib"
|
||||
// ...
|
||||
},
|
||||
"$schema": "./node_modules/nx/schemas/workspace-schema.json",
|
||||
"$schema": "./node_modules/nx/schemas/workspace-schema.json"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -45,12 +45,15 @@ inputs:
|
||||
### Explanation of Fields
|
||||
|
||||
- **name**:
|
||||
|
||||
- The name of the custom step.
|
||||
|
||||
- **description**:
|
||||
|
||||
- A description of what the custom step does.
|
||||
|
||||
- **definition**:
|
||||
|
||||
- **using**: The runtime environment. Supported values are `node` and `aggregate`.
|
||||
- **node**: If `using` is set to `node`, then only `main` and `post` can be used.
|
||||
- **aggregate**: If `using` is set to `aggregate`, then only `steps` can be used.
|
||||
|
||||
@@ -87,6 +87,7 @@ Nx Cloud provides the following images:
|
||||
- `ubuntu22.04-node20.11-v5`
|
||||
- added elevated permission access via `sudo`
|
||||
- `ubuntu22.04-node20.11-v6`
|
||||
|
||||
- `corepack` is enabled by default
|
||||
- default global package manager versions:
|
||||
- `npm` v10
|
||||
@@ -738,20 +739,3 @@ launch-templates:
|
||||
# This is a safer approach to prevent leaking tokens/passwords
|
||||
echo "SOME_VALUE: $SOME_VALUE"
|
||||
```
|
||||
|
||||
## Nx Workspace in a Subdirectory
|
||||
|
||||
If your Nx workspace is in a subdirectory of your repository, set `NX_WORKING_DIRECTORY` in your launch template:
|
||||
|
||||
```yaml
|
||||
launch-templates:
|
||||
my-template:
|
||||
resource-class: 'docker_linux_amd64/medium'
|
||||
image: 'ubuntu22.04-node20.11-v9'
|
||||
env:
|
||||
NX_WORKING_DIRECTORY: './client'
|
||||
init-steps:
|
||||
# ...
|
||||
```
|
||||
|
||||
The `install-node-modules` step automatically respects this variable (but can be overridden at the step level if your lockfile is hosted at the root). For other steps, set the working directory manually.
|
||||
|
||||
@@ -58,16 +58,6 @@ filter: 'type:References'
|
||||
- Chore: Released Helm chart `1.0.0` for Nx Cloud
|
||||
- Review the [migration guide](https://github.com/nrwl/nx-cloud-helm/blob/main/charts/nx-cloud/MIGRATION.md) before upgrading
|
||||
|
||||
### 2025.07.7
|
||||
|
||||
- Fix: Resolve zod dependency issues caused by Docker images being built without package-lock file
|
||||
- Fix: Normalize S3 bucket configuration to support assumedRole authentication for workspace data and conformance rule buckets
|
||||
- Feat: CIPE summary table updated to display CIPE link outside the table for improved readability
|
||||
|
||||
### 2025.07.4 - 2025.07.6
|
||||
|
||||
- Note: These versions had issues and should be skipped. Please use 2025.07.7 or later.
|
||||
|
||||
### 2025.07.3
|
||||
|
||||
- Fix: use short link when generating DTE summary URLs for CI Pipeline Executions
|
||||
@@ -182,10 +172,12 @@ nxApi:
|
||||
### 2025.03.2
|
||||
|
||||
- Feat: Nx Agents "bundled executors"
|
||||
|
||||
- up until now, the "executor" binaries that run on each Nx Agent (and know how to parse your agents.yaml and run each step) had to be downloaded separately from an external bucket
|
||||
- this made the on-prem upgrade process more difficult, as it required a separate step to download the executor and then upload it in the correct folder on an internally available repository
|
||||
- now, the executors are available as Docker images that can be imported alongside all your other NxCloud images
|
||||
- to get started:
|
||||
|
||||
- when upgrading to this version, make sure you also pull in the executor image `nxprivatecloud/nx-cloud-workflow-executor:2025.03.2`([link](https://hub.docker.com/repository/docker/nxprivatecloud/nx-cloud-workflow-executor/tags/2025.03.2/sha256-a42835a3126f21178af87f02b68d68fec1ff0654d37a57855a762c01e7795a6b))
|
||||
- as part of your controller [args](https://github.com/nrwl/nx-cloud-helm/blob/main/charts/nx-agents/values.yaml#L76) pass this option:
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ The `nx add @nx/owners` command should have registered the `@nx/owners:sync-code
|
||||
// nx.json
|
||||
{
|
||||
"sync": {
|
||||
"globalGenerators": ["@nx/owners:sync-codeowners-file"],
|
||||
},
|
||||
"globalGenerators": ["@nx/owners:sync-codeowners-file"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -74,10 +74,10 @@ It is also often helpful to add `nx sync` as a git push hook or git commit hook.
|
||||
// See https://nx.dev/docs/reference/nx-commands#nx-run-many
|
||||
"projects": ["my-rust-app", "rust-*", "tag:rust"],
|
||||
// File globs
|
||||
"files": [".github/workflows/**/*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"files": [".github/workflows/**/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -103,10 +103,10 @@ It is also often helpful to add `nx sync` as a git push hook or git commit hook.
|
||||
// See https://nx.dev/docs/reference/nx-commands#nx-run-many
|
||||
"projects": ["my-rust-app", "rust-*", "tag:rust"],
|
||||
// File globs
|
||||
"files": [".github/workflows/**/*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"files": [".github/workflows/**/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -134,8 +134,8 @@ If you are using GitLab, you can specify CODEOWNERS [sections](https://docs.gitl
|
||||
// See https://nx.dev/docs/reference/nx-commands#nx-run-many
|
||||
"projects": ["my-rust-app", "rust-*", "tag:rust"],
|
||||
// File globs
|
||||
"files": [".github/workflows/**/*"],
|
||||
},
|
||||
"files": [".github/workflows/**/*"]
|
||||
}
|
||||
],
|
||||
// (Optional)
|
||||
"sections": [
|
||||
@@ -150,10 +150,10 @@ If you are using GitLab, you can specify CODEOWNERS [sections](https://docs.gitl
|
||||
// (Optional) Do not require any approvals, just notify the owners
|
||||
"optional": true,
|
||||
// Same format as the root patterns
|
||||
"patterns": [],
|
||||
},
|
||||
],
|
||||
},
|
||||
"patterns": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -193,25 +193,25 @@ If you are using GitLab, you can specify CODEOWNERS [sections](https://docs.gitl
|
||||
{
|
||||
"description": "Joe should double check all changes to rust code",
|
||||
"projects": ["tag:rust"],
|
||||
"owners": ["@joelovesrust"],
|
||||
"owners": ["@joelovesrust"]
|
||||
},
|
||||
{
|
||||
"description": "The Finance team owns these projects",
|
||||
"projects": ["finance-*"],
|
||||
"owners": ["@finance-team"],
|
||||
"owners": ["@finance-team"]
|
||||
},
|
||||
{
|
||||
"description": "Alice, Bob and Cecil work together on these projects",
|
||||
"projects": ["admin", "booking", "cart"],
|
||||
"owners": ["@alice", "@bob", "@cecil"],
|
||||
"owners": ["@alice", "@bob", "@cecil"]
|
||||
},
|
||||
{
|
||||
"description": "CI Workflows",
|
||||
"files": [".github/workflows/**/*"],
|
||||
"owners": ["@devops"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"owners": ["@devops"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -243,25 +243,25 @@ If you are using GitLab, you can specify CODEOWNERS [sections](https://docs.gitl
|
||||
{
|
||||
"description": "Joe should double check all changes to rust code",
|
||||
"projects": ["tag:rust"],
|
||||
"owners": ["@joelovesrust"],
|
||||
"owners": ["@joelovesrust"]
|
||||
},
|
||||
{
|
||||
"description": "The Finance team owns these projects",
|
||||
"projects": ["finance-*"],
|
||||
"owners": ["@finance-team"],
|
||||
"owners": ["@finance-team"]
|
||||
},
|
||||
{
|
||||
"description": "Alice, Bob and Cecil work together on these projects",
|
||||
"projects": ["admin", "booking", "cart"],
|
||||
"owners": ["@alice", "@bob", "@cecil"],
|
||||
"owners": ["@alice", "@bob", "@cecil"]
|
||||
},
|
||||
{
|
||||
"description": "CI Workflows",
|
||||
"files": [".github/workflows/**/*"],
|
||||
"owners": ["@devops"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"owners": ["@devops"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -293,13 +293,13 @@ If you are using GitLab, you can specify CODEOWNERS [sections](https://docs.gitl
|
||||
{
|
||||
"description": "Joe should double check all changes to rust code",
|
||||
"projects": ["tag:rust"],
|
||||
"owners": ["@joelovesrust"],
|
||||
"owners": ["@joelovesrust"]
|
||||
},
|
||||
{
|
||||
"description": "CI Workflows",
|
||||
"files": [".github/workflows/**/*"],
|
||||
"owners": ["@devops"],
|
||||
},
|
||||
"owners": ["@devops"]
|
||||
}
|
||||
],
|
||||
"sections": [
|
||||
{
|
||||
@@ -309,17 +309,17 @@ If you are using GitLab, you can specify CODEOWNERS [sections](https://docs.gitl
|
||||
"patterns": [
|
||||
{
|
||||
"description": "The Finance team owns these projects",
|
||||
"projects": ["finance-*"],
|
||||
"projects": ["finance-*"]
|
||||
},
|
||||
{
|
||||
"description": "Alice, Bob and Cecil work together on these projects",
|
||||
"projects": ["admin", "booking", "cart"],
|
||||
"owners": ["@alice", "@bob", "@cecil"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"owners": ["@alice", "@bob", "@cecil"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+6
-6
@@ -118,8 +118,8 @@ Finally, you need to configure your Nx cache in the `nx.json` file. The `contain
|
||||
{
|
||||
"azure": {
|
||||
"container": "mycontainer",
|
||||
"accountName": "myaccount",
|
||||
},
|
||||
"accountName": "myaccount"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -143,8 +143,8 @@ Nx will only show warnings when the remote cache is not writable. You can disabl
|
||||
{
|
||||
"azure": {
|
||||
// ...
|
||||
"localMode": "read-only",
|
||||
},
|
||||
"localMode": "read-only"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -155,7 +155,7 @@ The cache mode in CI can also be configured by setting `ciMode` to `read-only` o
|
||||
{
|
||||
"azure": {
|
||||
// ...
|
||||
"ciMode": "read-only",
|
||||
},
|
||||
"ciMode": "read-only"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -118,8 +118,8 @@ Finally, you need to configure your Nx cache in the `nx.json` file. The `bucket`
|
||||
// nx.json
|
||||
{
|
||||
"gcs": {
|
||||
"bucket": "my-bucket",
|
||||
},
|
||||
"bucket": "my-bucket"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -142,8 +142,8 @@ Nx will only show warnings when the remote cache is not writable. You can disabl
|
||||
{
|
||||
"gcs": {
|
||||
// ...
|
||||
"localMode": "read-only",
|
||||
},
|
||||
"localMode": "read-only"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -154,7 +154,7 @@ The cache mode in CI can also be configured by setting `ciMode` to `read-only` o
|
||||
{
|
||||
"gcs": {
|
||||
// ...
|
||||
"ciMode": "read-only",
|
||||
},
|
||||
"ciMode": "read-only"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -141,8 +141,8 @@ Storing your credentials in the `nx.json` file is the least secure of the 4 auth
|
||||
"s3": {
|
||||
"ssoProfile": "default",
|
||||
"accessKeyId": "MYACCESSKEYID",
|
||||
"secretAccessKey": "MYSECRETACCESSKEY",
|
||||
},
|
||||
"secretAccessKey": "MYSECRETACCESSKEY"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -163,8 +163,8 @@ Regardless of how you manage your AWS authentication, you need to configure your
|
||||
"s3": {
|
||||
"region": "us-east-1",
|
||||
"bucket": "my-bucket",
|
||||
"encryptionKey": "create-your-own-key",
|
||||
},
|
||||
"encryptionKey": "create-your-own-key"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -190,8 +190,8 @@ Below is an example on how to connect to MinIO:
|
||||
"forcePathStyle": true,
|
||||
"accessKeyId": "abc1234",
|
||||
"secretAccessKey": "4321cba",
|
||||
"disableChecksum": true,
|
||||
},
|
||||
"disableChecksum": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -219,8 +219,8 @@ Nx will only show warnings when the remote cache is not writable. You can disabl
|
||||
"s3": {
|
||||
"region": "us-east-1",
|
||||
"bucket": "my-bucket",
|
||||
"localMode": "read-only",
|
||||
},
|
||||
"localMode": "read-only"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -232,8 +232,8 @@ The cache mode in CI can also be configured by setting `ciMode` to `read-only` o
|
||||
"s3": {
|
||||
"region": "us-east-1",
|
||||
"bucket": "my-bucket",
|
||||
"ciMode": "read-only",
|
||||
},
|
||||
"ciMode": "read-only"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ The following environment variables are ones that you can set to change the beha
|
||||
| `NX_TASKS_RUNNER_DYNAMIC_OUTPUT` | boolean | If set to `false`, will use non-dynamic terminal output strategy (what you see in CI), even when you terminal can support the dynamic version |
|
||||
| `NX_TUI` | boolean | If set to `true` or `false`, will enable or disable the Terminal UI (TUI) for running tasks. TUI provides an interactive visual interface for task execution |
|
||||
| `NX_TUI_AUTO_EXIT` | boolean/number | Controls whether the TUI automatically exits after tasks finish. If `true`, exits immediately. If `false`, never exits automatically. If a number, shows a countdown for that many seconds before exiting |
|
||||
| `NX_USE_LOCAL` | boolean | If set to `true`, Nx will use the locally installed version instead of downloading the latest version from npm for commands like `nx init` and `nx migrate`. |
|
||||
| `NX_VERBOSE_LOGGING` | boolean | If set to `true`, will print debug information useful for troubleshooting |
|
||||
| `NX_DRY_RUN` | boolean | If set to `true`, will perform a dry run of the generator. No files will be created and no packages will be installed. |
|
||||
| `NX_INTERACTIVE` | boolean | If set to `true`, will allow Nx to prompt you in the terminal to answer some further questions when running generators. |
|
||||
@@ -43,9 +42,7 @@ The following environment variables are ones that you can set to change the beha
|
||||
| `NX_BATCH_MODE` | boolean | If set to `true`, Nx will run task(s) in batches for executors which support batches. |
|
||||
| `NX_SKIP_LOG_GROUPING` | boolean | If set to `true`, Nx will not group command's logs on CI. |
|
||||
| `NX_MIGRATE_CLI_VERSION` | string | The version of Nx to use for running the `nx migrate` command. If not set, it defaults to `latest`. |
|
||||
| `NX_MIGRATE_SKIP_INSTALL` | boolean | If set to `true`, `nx migrate --run-migrations` will not automatically perform the installation of the packages. |
|
||||
| `NX_MIGRATE_SKIP_REGISTRY_FETCH` | boolean | If set to `true`, will skip fetching metadata from the registry and instead use the installation method directly. |
|
||||
| `NX_MIGRATE_USE_LOCAL` | boolean | If set to `true`, will use the locally installed version of `nx` instead of downloading the latest version to run the `nx migrate` command. |
|
||||
| `NX_LOAD_DOT_ENV_FILES` | boolean | If set to 'false', Nx will not load any environment files (e.g. `.local.env`, `.env.local`) |
|
||||
| `NX_MAX_CACHE_SIZE` | string | Alternative to configuring `maxCacheSize` in `nx.json`. Defines the maximum size of the local task cache. See [`maxCacheSize`](/docs/reference/nx-json#max-cache-size) for supported units and behavior details. |
|
||||
| `NX_NATIVE_FILE_CACHE_DIRECTORY` | string | The cache for native `.node` files is stored under a global temp directory by default. Set this variable to use a different directory. This is interpreted as an absolute path. |
|
||||
@@ -53,16 +50,6 @@ The following environment variables are ones that you can set to change the beha
|
||||
| `NX_FORMAT_SORT_TSCONFIG_PATHS` | boolean | If set to `true`, generators will sort the TypeScript path mappings in the root tsconfig file. |
|
||||
| `NX_SKIP_VSCODE_EXTENSION_INSTALL` | boolean | If set to `true`, skips the automatic installation of the Nx Console extension for supported editors. Set this in environments where the temp file that we store this information in otherwise isn't accessible. |
|
||||
|
||||
## Plugin Environment Variables
|
||||
|
||||
The following environment variables can be used to disable specific Nx plugins. This is useful in CI environments where the required tooling (e.g., Java) is not available.
|
||||
|
||||
| Property | Type | Description |
|
||||
| ------------------- | ------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `NX_DOTNET_DISABLE` | boolean | If set to `true`, disables the `@nx/dotnet` plugin. Useful in environments where .NET SDK is not available. |
|
||||
| `NX_GRADLE_DISABLE` | boolean | If set to `true`, disables the `@nx/gradle` plugin. Useful in environments where Java/Gradle is not available. |
|
||||
| `NX_MAVEN_DISABLE` | boolean | If set to `true`, disables the `@nx/maven` plugin. Useful in environments where Java/Maven is not available. |
|
||||
|
||||
Nx will set the following environment variables so they can be accessible within the process even outside of executors and generators.
|
||||
|
||||
| Property | Type | Description |
|
||||
@@ -82,21 +69,20 @@ The following environment variables are specific to Nx Cloud and can be used to
|
||||
Similar to the Nx CLI, Nx Cloud also used the `NX_VERBOSE_LOGGING` environment variable to output debug information
|
||||
{% /aside %}
|
||||
|
||||
| Property | Type | Description |
|
||||
| ------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `NX_BRANCH` | string | The current branch name. For most CI providers, `nx-cloud` determines this automatically. Must be set to the PR number for GitHub, BitBucket and GitLab integrations to work properly. |
|
||||
| `NX_CLOUD_DISABLE_METRICS_COLLECTION` | boolean | Disables collection of CPU and memory metrics during task execution (enabled by default for enterprise users on Nx 22.1+). See [Task Resource Usage](/docs/guides/nx-cloud/ci-resource-usage). |
|
||||
| `NX_CLOUD_METRICS_DIRECTORY` | string | Directory where Nx writes resource metrics during task execution. See [Task Resource Usage](/docs/guides/nx-cloud/ci-resource-usage). |
|
||||
| `NX_CI_EXECUTION_ID` | string | A unique identifier for the current CI run or job. For most CI providers, `nx-cloud` determines this automatically. The value on the main job must match the value on all agents. |
|
||||
| `NX_CI_EXECUTION_ENV` | string | Used when you have multiple main jobs (e.g., running CI on both Linux and Windows). The main job with this env variable will connect to agents with the same env name. |
|
||||
| `NX_AGENT_LAUNCH_TEMPLATE` | string | Should only be used when running agents with Manual DTE. Attaches a launch template type to your agents to leverage assignment rules for task distribution. |
|
||||
| `NX_CLOUD_ACCESS_TOKEN` | string | Configure the Nx Cloud access token. Takes precedence over the `accessToken` property in `nx.json`. Common to have a read-only token in `nx.json` and a read-write token set via this environment variable in CI. |
|
||||
| `NX_CLOUD_API` | string | The URL of the Nx Cloud instance to connect to. Overrides `nxCloudUrl` in `nx.json`. |
|
||||
| `NX_CLOUD_ENCRYPTION_KEY` | string | Enable end-to-end encryption of artifacts. Artifacts will be encrypted/decrypted on your machine. Can also be set via the `encryptionKey` property in `nx.json`. |
|
||||
| `NX_CLOUD_NO_TIMEOUTS` | boolean | Disables the default 10-second timeout for Nx Cloud requests. |
|
||||
| `NX_NO_CLOUD` | boolean | If set to `true`, prevents Nx Cloud from being used for the current run. No remote cache will be used. Value cannot be set if using [distributed task execution](/docs/features/ci-features/distribute-task-execution) |
|
||||
| `NX_VERBOSE_LOGGING` | boolean | Outputs debug information about agents communicating with the main job. Useful for debugging cache misses and on-premises setup issues. |
|
||||
| `NX_WORKING_DIRECTORY` | string | The subdirectory containing your Nx workspace. Set this in your launch template if your Nx workspace is not at the repository root. Only used by Nx Agents. |
|
||||
| Property | Type | Description |
|
||||
| ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `NX_BRANCH` | string | The current branch name. For most CI providers, `nx-cloud` determines this automatically. Must be set to the PR number for GitHub, BitBucket and GitLab integrations to work properly. |
|
||||
| `NX_CLOUD_ENABLE_METRICS_COLLECTION` | boolean | Enables collection of CPU and memory metrics during task execution. Currently opt-in, but will be enabled by default in future Nx versions. See [Task Resource Usage](/docs/guides/nx-cloud/ci-resource-usage). |
|
||||
| `NX_CLOUD_METRICS_DIRECTORY` | string | Directory where Nx writes resource metrics during task execution. See [Task Resource Usage](/docs/guides/nx-cloud/ci-resource-usage). |
|
||||
| `NX_CI_EXECUTION_ID` | string | A unique identifier for the current CI run or job. For most CI providers, `nx-cloud` determines this automatically. The value on the main job must match the value on all agents. |
|
||||
| `NX_CI_EXECUTION_ENV` | string | Used when you have multiple main jobs (e.g., running CI on both Linux and Windows). The main job with this env variable will connect to agents with the same env name. |
|
||||
| `NX_AGENT_LAUNCH_TEMPLATE` | string | Should only be used when running agents with Manual DTE. Attaches a launch template type to your agents to leverage assignment rules for task distribution. |
|
||||
| `NX_CLOUD_ACCESS_TOKEN` | string | Configure the Nx Cloud access token. Takes precedence over the `accessToken` property in `nx.json`. Common to have a read-only token in `nx.json` and a read-write token set via this environment variable in CI. |
|
||||
| `NX_CLOUD_API` | string | The URL of the Nx Cloud instance to connect to. Overrides `nxCloudUrl` in `nx.json`. |
|
||||
| `NX_CLOUD_ENCRYPTION_KEY` | string | Enable end-to-end encryption of artifacts. Artifacts will be encrypted/decrypted on your machine. Can also be set via the `encryptionKey` property in `nx.json`. |
|
||||
| `NX_CLOUD_NO_TIMEOUTS` | boolean | Disables the default 10-second timeout for Nx Cloud requests. |
|
||||
| `NX_NO_CLOUD` | boolean | If set to `true`, prevents Nx Cloud from being used for the current run. No remote cache will be used. Value cannot be set if using [distributed task execution](/docs/features/ci-features/distribute-task-execution) |
|
||||
| `NX_VERBOSE_LOGGING` | boolean | Outputs debug information about agents communicating with the main job. Useful for debugging cache misses and on-premises setup issues. |
|
||||
|
||||
### Deprecated Nx Cloud Environment Variables
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ filter: 'type:References'
|
||||
---
|
||||
|
||||
When Nx [computes the hash for a given operation](/docs/concepts/how-caching-works), it takes into account the `inputs` of the target.
|
||||
The `inputs` are a list of **file sets**, **runtime** inputs, **environment variables**, and **working directory** that affect the output of the target.
|
||||
The `inputs` are a list of **file sets**, **runtime** inputs and **environment variables** that affect the output of the target.
|
||||
If any of the `inputs` change, the cache is invalidated and the target is re-run.
|
||||
|
||||
## Types of Inputs
|
||||
@@ -30,25 +30,18 @@ Changing source code will often change the behavior of a task. Nx can consider t
|
||||
Source file inputs are defined like this:
|
||||
|
||||
```jsonc
|
||||
// nx.json
|
||||
{
|
||||
"inputs": [
|
||||
"inputs": {
|
||||
"{projectRoot}/**/*", // All files in a project
|
||||
"{workspaceRoot}/.gitignore", // A specific file in the workspace
|
||||
"{projectRoot}/**/*.ts", // A glob pattern for files
|
||||
"!{projectRoot}/**/*.spec.ts", // Excluding files matching a glob pattern
|
||||
],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Source file inputs can be specified as strings with glob patterns. These patterns must be prefixed with either `{projectRoot}` or `{workspaceRoot}` to distinguish where the paths should be resolved from. `{workspaceRoot}` should only appear in the beginning of an input but `{projectRoot}` and `{projectName}` can be specified later in the input to interpolate the root or name of the project into the input location.
|
||||
|
||||
Alternatively, you can use the object format with the `fileset` property:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"inputs": [{ "fileset": "{projectRoot}/**/*" }],
|
||||
}
|
||||
```
|
||||
Source file inputs must be prefixed with either `{projectRoot}` or `{workspaceRoot}` to distinguish where the paths should be resolved from. `{workspaceRoot}` should only appear in the beginning of an input but `{projectRoot}` and `{projectName}` can be specified later in the input to interpolate the root or name of the project into the input location.
|
||||
|
||||
#### Token Behavior with Nested Projects
|
||||
|
||||
@@ -78,8 +71,8 @@ Tools and scripts will often use some environment variables to change their beha
|
||||
```jsonc
|
||||
{
|
||||
"inputs": [
|
||||
{ "env": "API_KEY" }, // this will include the value of $API_KEY in the cache hash
|
||||
],
|
||||
{ "env": "API_KEY" } // this will include the value of $API_KEY in the cache hash
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -89,29 +82,12 @@ You can use a Runtime input to provide a script which will output the informatio
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"inputs": [{ "runtime": "node --version" }],
|
||||
"inputs": [{ "runtime": "node --version" }]
|
||||
}
|
||||
```
|
||||
|
||||
This kind of input is often used to include versions of tools used to run the task. You should ensure that these scripts work on any platform where the workspace is used. Avoid using `.sh` or `.bat` files as these will not work across Windows and \*nix operating systems.
|
||||
|
||||
### Working Directory
|
||||
|
||||
Some tasks may behave differently depending on which directory they are run from. Nx can include the current working directory in the computation hash to ensure that tasks are re-run when the working directory changes. Working directory inputs are defined like this:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"inputs": [
|
||||
{ "workingDirectory": "relative" }, // Hash the path relative to workspace root
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The `workingDirectory` input accepts two values:
|
||||
|
||||
- `"relative"` - Hashes the relative path from the workspace root to the current working directory. This is useful when tasks should be invalidated when run from different subdirectories within the workspace.
|
||||
- `"absolute"` - Hashes the full absolute path of the current working directory. This is useful when tasks depend on the exact location on the filesystem. Notably, this will invalidate cache entries if the repository is cloned to a different location on the filesystem, such as between CI and local development environments.
|
||||
|
||||
### External Dependencies
|
||||
|
||||
Source code often imports from external dependencies installed through package managers. For example, a React application will likely import `react`. It is not needed to configure those `externalDependencies` directly. Nx will always consider external dependencies depended upon by any source code within the project.
|
||||
@@ -120,7 +96,7 @@ External dependencies can also be tools used to run tasks. Updating the versions
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"inputs": [{ "externalDependencies": ["jest"] }],
|
||||
"inputs": [{ "externalDependencies": ["jest"] }]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -136,9 +112,9 @@ The drawback of this assumption is that Nx will re-run the `lint` task even when
|
||||
{
|
||||
"targets": {
|
||||
"lint": {
|
||||
"command": "eslint .",
|
||||
},
|
||||
},
|
||||
"command": "eslint ."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -151,10 +127,10 @@ This default behavior can be overridden by adding any external dependency inputs
|
||||
"command": "eslint .",
|
||||
"inputs": [
|
||||
"default",
|
||||
{ "externalDependencies": ["eslint", "eslint-config-airbnb"] },
|
||||
],
|
||||
},
|
||||
},
|
||||
{ "externalDependencies": ["eslint", "eslint-config-airbnb"] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -168,43 +144,18 @@ When a task depends on another task, it is possible that the outputs of the depe
|
||||
{
|
||||
"inputs": [
|
||||
{ "dependentTasksOutputFiles": "**/*.d.ts" },
|
||||
{ "dependentTasksOutputFiles": "**/*.d.ts", "transitive": true },
|
||||
],
|
||||
{ "dependentTasksOutputFiles": "**/*.d.ts", "transitive": true }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The glob pattern is matched against the file paths resolved from workspace root. For example, if a dependent task has `outputs: ["{workspaceRoot}/dist/{projectRoot}"]` and the project root is `libs/my-lib`, the output path becomes `dist/libs/my-lib`.
|
||||
Files such as `dist/libs/my-lib/index.d.ts` would be matched by patterns `**/*.d.ts`, `dist/**/*.d.ts`, or `dist/libs/my-lib/**/*.d.ts`. Setting `transitive` to `true` will also include outputs of all task dependencies of this task in the [task pipeline](/docs/concepts/task-pipeline-configuration). It's possible the dependent tasks can change over time, so be careful to not overly scope the matching glob to prevent accidental false cache hits.
|
||||
The pattern will be matched with outputs of tasks which this task depends on. Setting `transitive` to `true` will also include outputs of all task dependencies of this task in the [task pipeline](/docs/concepts/task-pipeline-configuration).
|
||||
|
||||
### A subset of the root `tsconfig.json` or `tsconfig.base.json`
|
||||
|
||||
When a root `tsconfig.json` or `tsconfig.base.json` is present, Nx will always consider parts of the file which apply to the project of a task being run.
|
||||
This includes the full `compilerOptions` section and particular path mappings in the `compilerOptions.paths` property.
|
||||
This allows Nx to not invalidate every single task when a path mapping is added or removed from the root `tsconfig.json` file
|
||||
|
||||
### Named Inputs from Other Projects
|
||||
|
||||
You can reference named inputs from specific projects or from project dependencies using the object format with the `input` property:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"inputs": [
|
||||
// Reference a named input from specific project(s)
|
||||
{ "input": "production", "projects": "mylib" },
|
||||
{ "input": "production", "projects": ["mylib", "myapp"] },
|
||||
|
||||
// Reference a named input from the current project
|
||||
// Equivalent to: { "input": "production" }
|
||||
"production",
|
||||
|
||||
// Reference a named input from all project dependencies
|
||||
// Equivalent to: { "input": "production", "dependencies": true }
|
||||
"^production",
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The `projects` property can be a string or an array of strings specifying which project(s) to reference the named input from. Using just the string name (e.g., `"production"`) is shorthand for referencing the named input from the current project. Prefixing with `^` (e.g., `"^production"`) references the named input from all project dependencies.
|
||||
This allows Nx to to not invalidate every single task when a path mapping is added or removed from the root `tsconfig.json` file
|
||||
|
||||
## Named Inputs
|
||||
|
||||
@@ -222,8 +173,8 @@ Named inputs defined in `nx.json` can be used by any project in the workspace in
|
||||
// nx.json
|
||||
{
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*"], // Default Inputs
|
||||
},
|
||||
"default": ["{projectRoot}/**/*"] // Default Inputs
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -276,8 +227,8 @@ By default, Nx Workspaces are generated with the following named inputs:
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*", "sharedGlobals"], // Default Inputs
|
||||
"production": ["default", "!{projectRoot}/jest.config.ts"], // Production Inputs
|
||||
"sharedGlobals": [], // Shared Global Inputs
|
||||
},
|
||||
"sharedGlobals": [] // Shared Global Inputs
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -307,9 +258,9 @@ It is common for most tasks to consider a set of inputs for the project it belon
|
||||
"name": "myreactapp",
|
||||
"targets": {
|
||||
"test": {
|
||||
"inputs": ["default", "^production", "{projectRoot}/jest.config.js"],
|
||||
},
|
||||
},
|
||||
"inputs": ["default", "^production", "{projectRoot}/jest.config.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -128,9 +128,9 @@ Plugins use config files to infer tasks for projects. You can specify which conf
|
||||
{
|
||||
"plugin": "@nx/jest/plugin",
|
||||
"include": ["packages/**/*"], // include any projects in the packages folder
|
||||
"exclude": ["**/*-e2e/**/*"], // exclude any projects in a *-e2e folder
|
||||
},
|
||||
],
|
||||
"exclude": ["**/*-e2e/**/*"] // exclude any projects in a *-e2e folder
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -388,8 +388,8 @@ If you want to limit the projects that `nx release` targets, you can use the `pr
|
||||
"release": {
|
||||
// Here we are configuring nx release to target all projects
|
||||
// except the one called "ignore-me"
|
||||
"projects": ["*", "!ignore-me"],
|
||||
},
|
||||
"projects": ["*", "!ignore-me"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -403,8 +403,8 @@ The `projectsRelationship` property tells Nx whether to release projects indepen
|
||||
"release": {
|
||||
// Here we are configuring nx release to release projects
|
||||
// independently, as opposed to the default of "fixed"
|
||||
"projectsRelationship": "independent",
|
||||
},
|
||||
"projectsRelationship": "independent"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -459,9 +459,9 @@ Example patterns and their results:
|
||||
"requireSemver": true,
|
||||
"strictPreid": true,
|
||||
"preferDockerVersion": false,
|
||||
"checkAllBranchesWhen": "main",
|
||||
},
|
||||
},
|
||||
"checkAllBranchesWhen": "main"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -476,8 +476,8 @@ Example patterns and their results:
|
||||
"releaseTagPatternRequireSemver": true,
|
||||
"releaseTagPatternStrictPreid": true,
|
||||
"releaseTagPatternPreferDockerVersion": false,
|
||||
"releaseTagPatternCheckAllBranchesWhen": "main",
|
||||
},
|
||||
"releaseTagPatternCheckAllBranchesWhen": "main"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -513,10 +513,10 @@ Core version options are therefore directly at the top level of the `version` pr
|
||||
"manifestRootsToUpdate": ["dist/packages/{projectName}"],
|
||||
// Ecosystem-specific options
|
||||
"versionActionsOptions": {
|
||||
"skipLockFileUpdate": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"skipLockFileUpdate": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -556,9 +556,9 @@ The `changelog.workspaceChangelog` property configures the workspace changelog.
|
||||
"release": {
|
||||
"changelog": {
|
||||
// This disables the workspace changelog
|
||||
"workspaceChangelog": false,
|
||||
},
|
||||
},
|
||||
"workspaceChangelog": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -572,10 +572,10 @@ The `changelog.workspaceChangelog` property configures the workspace changelog.
|
||||
// changelog contents
|
||||
"createRelease": "github",
|
||||
// This will disable creating a workspace CHANGELOG.md file
|
||||
"file": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
"file": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -589,9 +589,9 @@ The `changelog.projectChangelogs` property configures the project changelogs. It
|
||||
"release": {
|
||||
"changelog": {
|
||||
// This enables project changelogs with the default options
|
||||
"projectChangelogs": true,
|
||||
},
|
||||
},
|
||||
"projectChangelogs": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -606,10 +606,10 @@ The `changelog.projectChangelogs` property configures the project changelogs. It
|
||||
"createRelease": "github",
|
||||
// This will disable creating any project level CHANGELOG.md
|
||||
// files
|
||||
"file": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
"file": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -624,10 +624,10 @@ By default, changelog entries are prepended to existing changelog files. To comp
|
||||
"changelog": {
|
||||
"workspaceChangelog": {
|
||||
// Replaces the entire CHANGELOG.md file with the new content
|
||||
"replaceExistingContents": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"replaceExistingContents": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -647,9 +647,9 @@ The `git` property configures the automated git operations that take place as pa
|
||||
"commit": true,
|
||||
// This will enable create a git for the overall release, or
|
||||
// one tag per project for independent project releases
|
||||
"tag": false,
|
||||
},
|
||||
},
|
||||
"tag": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -666,8 +666,8 @@ The `docker` property configures Docker image versioning and publishing when usi
|
||||
{
|
||||
"release": {
|
||||
// Simple configuration - enables Docker with defaults
|
||||
"docker": true,
|
||||
},
|
||||
"docker": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -684,7 +684,7 @@ The `docker` property configures Docker image versioning and publishing when usi
|
||||
"production": "{currentDate|YYMM.DD}.{shortCommitSha}",
|
||||
"hotfix": "{currentDate|YYMM.DD}.{shortCommitSha}-hotfix",
|
||||
"staging": "{currentDate|YYMM.DD}-staging",
|
||||
"development": "{currentDate|YYMM.DD}-dev-{shortCommitSha}",
|
||||
"development": "{currentDate|YYMM.DD}-dev-{shortCommitSha}"
|
||||
},
|
||||
|
||||
// Skip Docker versioning for these projects to prevent versioning with other tools like NPM
|
||||
@@ -695,9 +695,9 @@ The `docker` property configures Docker image versioning and publishing when usi
|
||||
"repositoryName": "myorg",
|
||||
|
||||
// Docker registry URL
|
||||
"registryUrl": "docker.io",
|
||||
},
|
||||
},
|
||||
"registryUrl": "docker.io"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -719,11 +719,11 @@ When configuring the `@nx/docker` plugin in `nx.json`, you can customize the beh
|
||||
// Skip the default --tag argument
|
||||
"skipDefaultTag": true,
|
||||
// You must provide your own tags via args
|
||||
"args": ["--tag myorg/myapp:latest", "--tag myorg/myapp:1.0.0"],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
"args": ["--tag myorg/myapp:latest", "--tag myorg/myapp:1.0.0"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -797,11 +797,11 @@ These are global configuration options for the [`nx sync`](/docs/reference/nx-co
|
||||
"globalGenerators": ["my-plugin:my-sync-generator"],
|
||||
"generatorOptions": {
|
||||
"my-plugin:my-sync-generator": {
|
||||
"verbose": true,
|
||||
},
|
||||
"verbose": true
|
||||
}
|
||||
},
|
||||
"disabledTaskSyncGenerators": ["other-plugin:problematic-generator"],
|
||||
},
|
||||
"disabledTaskSyncGenerators": ["other-plugin:problematic-generator"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -917,14 +917,14 @@ The `conformance` property in `nx.json` configures the usage of [Nx Conformance]
|
||||
{
|
||||
"rule": "@nx/conformance/enforce-module-boundaries",
|
||||
"status": "evaluated",
|
||||
"explanation": "This rule ensures proper module boundaries are maintained across the workspace",
|
||||
"explanation": "This rule ensures proper module boundaries are maintained across the workspace"
|
||||
},
|
||||
{
|
||||
"rule": "./tools/local-conformance-rules/check-project.ts",
|
||||
"projects": ["*"],
|
||||
"options": {
|
||||
"strictMode": true,
|
||||
},
|
||||
"strictMode": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rule": "nx-cloud://my-custom-rule",
|
||||
@@ -932,13 +932,13 @@ The `conformance` property in `nx.json` configures the usage of [Nx Conformance]
|
||||
"frontend-*",
|
||||
{
|
||||
"matcher": "backend-legacy",
|
||||
"explanation": "Legacy backend project is exempt until migration is complete",
|
||||
},
|
||||
"explanation": "Legacy backend project is exempt until migration is complete"
|
||||
}
|
||||
],
|
||||
"status": "enforced",
|
||||
},
|
||||
],
|
||||
},
|
||||
"status": "enforced"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -974,7 +974,7 @@ You can also use objects with `matcher` and `explanation` properties to document
|
||||
"rule": "my-rule",
|
||||
// Here we are configuring the rule to apply to all frontend projects
|
||||
// except the one called "frontend-legacy"
|
||||
"projects": ["frontend-*", "!frontend-legacy"],
|
||||
"projects": ["frontend-*", "!frontend-legacy"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -985,9 +985,9 @@ You can also use objects with `matcher` and `explanation` properties to document
|
||||
"frontend-*",
|
||||
{
|
||||
"matcher": "!frontend-legacy",
|
||||
"explanation": "Exempt until migration to new architecture is complete",
|
||||
},
|
||||
],
|
||||
"explanation": "Exempt until migration to new architecture is complete"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -88,16 +88,16 @@ The following configuration creates `build` and `test` targets for Nx.
|
||||
{
|
||||
"name": "mylib",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"test": "jest"
|
||||
},
|
||||
"nx": {
|
||||
// you could also do this in "scripts", but this "targets" configuration also supports Nx executors
|
||||
"targets": {
|
||||
"build": {
|
||||
"command": "tsc -p tsconfig.lib.json",
|
||||
},
|
||||
},
|
||||
},
|
||||
"command": "tsc -p tsconfig.lib.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -113,15 +113,15 @@ The following configuration creates `build` and `test` targets for Nx.
|
||||
"executor": "@nx/jest:jest",
|
||||
"options": {
|
||||
/* ... */
|
||||
},
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"options": {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -142,27 +142,27 @@ Below are some more complete examples of project configuration files. For a more
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "tsc -p tsconfig.lib.json", // the actual command here is arbitrary
|
||||
"ignored": "exit 1",
|
||||
"ignored": "exit 1"
|
||||
},
|
||||
"nx": {
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*"],
|
||||
"production": ["!{projectRoot}/**/*.spec.tsx"],
|
||||
"production": ["!{projectRoot}/**/*.spec.tsx"]
|
||||
},
|
||||
"targets": {
|
||||
"build": {
|
||||
"inputs": ["production", "^production"],
|
||||
"outputs": ["{workspaceRoot}/dist/libs/mylib"],
|
||||
"dependsOn": ["^build"],
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"test": {
|
||||
"inputs": ["default", "^production"],
|
||||
"outputs": [],
|
||||
"dependsOn": ["build"],
|
||||
},
|
||||
"dependsOn": ["build"]
|
||||
}
|
||||
},
|
||||
"includedScripts": ["test", "build"], // If you want to limit the scripts Nx sees, you can specify a list here.
|
||||
},
|
||||
"includedScripts": ["test", "build"] // If you want to limit the scripts Nx sees, you can specify a list here.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -259,16 +259,16 @@ A typical set of inputs may look like this:
|
||||
{
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*"], // every file in the project
|
||||
"production": ["default", "!{projectRoot}/**/*.spec.tsx"], // except test files
|
||||
"production": ["default", "!{projectRoot}/**/*.spec.tsx"] // except test files
|
||||
},
|
||||
"targets": {
|
||||
"build": {
|
||||
"inputs": [
|
||||
"production", // this project's production files
|
||||
{ "externalDependencies": ["vite"] }, // the version of the vite package
|
||||
],
|
||||
},
|
||||
},
|
||||
{ "externalDependencies": ["vite"] } // the version of the vite package
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -642,10 +642,10 @@ target does:
|
||||
"targets": {
|
||||
"build": {
|
||||
"metadata": {
|
||||
"description": "Build the application for production",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "Build the application for production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -665,8 +665,8 @@ You can annotate your projects with `tags` as follows:
|
||||
{
|
||||
"name": "mylib",
|
||||
"nx": {
|
||||
"tags": ["scope:myteam"],
|
||||
},
|
||||
"tags": ["scope:myteam"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -677,7 +677,7 @@ You can annotate your projects with `tags` as follows:
|
||||
// project.json
|
||||
{
|
||||
"root": "libs/mylib",
|
||||
"tags": ["scope:myteam"],
|
||||
"tags": ["scope:myteam"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -699,8 +699,8 @@ Nx uses powerful source-code analysis to figure out your workspace's project gra
|
||||
{
|
||||
"name": "mylib",
|
||||
"nx": {
|
||||
"implicitDependencies": ["anotherlib"],
|
||||
},
|
||||
"implicitDependencies": ["anotherlib"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -711,7 +711,7 @@ Nx uses powerful source-code analysis to figure out your workspace's project gra
|
||||
// project.json
|
||||
{
|
||||
"root": "libs/mylib",
|
||||
"implicitDependencies": ["anotherlib"],
|
||||
"implicitDependencies": ["anotherlib"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -795,9 +795,9 @@ Projects with Docker images can override the global Docker configuration:
|
||||
"release": {
|
||||
"docker": {
|
||||
// Override the repository name for this specific project
|
||||
"repositoryName": "acme/api",
|
||||
},
|
||||
},
|
||||
"repositoryName": "acme/api"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -813,8 +813,8 @@ project:
|
||||
{
|
||||
"name": "admin",
|
||||
"metadata": {
|
||||
"description": "This is the admin application",
|
||||
},
|
||||
"description": "This is the admin application"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+9
-19
@@ -20,18 +20,14 @@ We provide a recommended version, and it is usually the latest minor version of
|
||||
|
||||
| Angular Version | **Nx Version _(recommended)_** | Nx Version _(range)_ |
|
||||
| --------------- | ------------------------------ | ---------------------------------------- |
|
||||
| ~21.1.0 | **latest** | >=22.4.0 <=latest |
|
||||
| ~21.0.0 | **latest** | >=22.3.0 <=latest |
|
||||
| ~20.3.0 | **latest** | >=21.6.1 <=latest |
|
||||
| ~20.2.0 | **latest** | >=21.5.1 <=latest |
|
||||
| ~20.1.0 | **latest** | >=21.3.0 <=latest |
|
||||
| ~20.0.0 | **latest** | >=21.2.0 <=latest |
|
||||
| ~19.2.0 | **latest** | >=20.5.0 <=latest |
|
||||
| ~19.1.0 | **latest** | >=20.4.0 <=latest |
|
||||
| ~19.0.0 | **latest** | >=20.2.0 <=latest |
|
||||
| ~18.2.0 | **~22.2.0** | >=19.6.0 <22.3.0 |
|
||||
| ~18.1.0 | **~22.2.0** | >=19.5.0 <22.3.0 |
|
||||
| ~18.0.0 | **~22.2.0** | >=19.1.0 <22.3.0 |
|
||||
| ~18.2.0 | **latest** | >=19.6.0 <=latest |
|
||||
| ~18.1.0 | **latest** | >=19.5.0 <=latest |
|
||||
| ~18.0.0 | **latest** | >=19.1.0 <=latest |
|
||||
| ~17.3.0 | **~21.1.0** | >=18.2.0 <21.2.0 |
|
||||
| ~17.2.0 | **~21.1.0** | >=18.1.1 <21.2.0 |
|
||||
| ~17.1.0 | **~21.1.0** | >=17.3.0 <21.2.0 |
|
||||
@@ -56,16 +52,10 @@ Additionally, you can check the supported versions of Node and Typescript for th
|
||||
|
||||
## Nx and Angular Rspack Version Compatibility Matrix
|
||||
|
||||
Below is a reference table that matches versions of [Angular Rspack](/docs/technologies/angular/angular-rspack/introduction) to the versions of Angular (lower than 20.2.0) and Nx that is compatible with it.
|
||||
Below is a reference table that matches versions of [Angular Rspack](/docs/technologies/angular/angular-rspack/introduction) to the versions of Angular and Nx that is compatible with it.
|
||||
|
||||
{% aside type="note" title="Newer Angular versions" %}
|
||||
The table below only shows the version of Angular Rspack that is compatible with Angular versions lower than 20.2.0. Starting with Angular 20.2.0, the Angular Rspack version to install is aligned with the Nx version, so refer to [the table above](#nx-and-angular-version-compatibility-matrix).
|
||||
{% /aside %}
|
||||
|
||||
| Angular Version | Angular Rspack Version | Nx Version |
|
||||
| --------------- | ---------------------- | ------------------- |
|
||||
| ~20.1.0 | **~21.2.0** | >= 21.1.0 <= 21.5.0 |
|
||||
| ~20.0.0 | **~21.1.0** | >= 21.1.0 <= 21.5.0 |
|
||||
| ~19.2.0 | **~20.8.0** | >= 20.8.1 <= 21.1.0 |
|
||||
| ~19.2.0 | **~20.7.0** | >= 20.8.1 <= 21.1.0 |
|
||||
| ~19.2.0 | **~20.6.0** | >= 20.6.0 <= 21.1.0 |
|
||||
| Angular Rspack | Angular | Nx |
|
||||
| -------------- | ----------- | ------------------- |
|
||||
| ~20.8.0 | **~19.2.0** | >= 20.8.1 <= latest |
|
||||
| ~20.7.0 | **~19.2.0** | >= 20.8.1 <= latest |
|
||||
| ~20.6.0 | **~19.2.0** | >= 20.6.0 <= latest |
|
||||
|
||||
+3
-64
@@ -19,75 +19,14 @@ For the most up-to-date installation instructions, refer to the official Tailwin
|
||||
|
||||
### Tailwind CSS v4
|
||||
|
||||
Tailwind CSS v4 [automatically detects classes from source files](https://tailwindcss.com/docs/detecting-classes-in-source-files). However, with Angular's PostCSS plugin, scanning starts from the workspace root by default. This means classes from all libraries end up in your production CSS, even unused ones.
|
||||
|
||||
To avoid bloated CSS, restrict scanning to your app folder and explicitly add your library dependencies:
|
||||
For Tailwind CSS v4, classes are [automatically detected from source files](https://tailwindcss.com/docs/detecting-classes-in-source-files). To register workspace libraries, add the following configuration to your stylesheet where you configure TailwindCSS.
|
||||
|
||||
```css
|
||||
// apps/myapp/src/styles.css
|
||||
@import "tailwindcss" source("./app");
|
||||
|
||||
@source "../../../libs/ui";
|
||||
@source "../../../libs/shared";
|
||||
@import 'tailwindcss';
|
||||
@source "../../../libs";
|
||||
```
|
||||
|
||||
#### Automating @source directives
|
||||
|
||||
Manually maintaining `@source` directives is tedious and error-prone. Use [`@juristr/nx-tailwind-sync`](https://www.npmjs.com/package/@juristr/nx-tailwind-sync) to automate this based on your project's dependency graph.
|
||||
|
||||
Install the package:
|
||||
|
||||
```shell
|
||||
npm install @juristr/nx-tailwind-sync
|
||||
```
|
||||
|
||||
Register the sync generator for your application's `build` and `serve` targets:
|
||||
|
||||
{% tabs syncKey="project-config-file" %}
|
||||
{% tabitem label="project.json" %}
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "myapp",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular/build:application",
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@angular/build:dev-server",
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% tabitem label="package.json" %}
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "myapp",
|
||||
"nx": {
|
||||
"targets": {
|
||||
"build": {
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
},
|
||||
"serve": {
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% /tabs %}
|
||||
|
||||
When you run `nx build myapp` or `nx serve myapp`, the sync generator analyzes your dependency graph and updates your `styles.css` with the correct `@source` directives automatically.
|
||||
|
||||
For more details on why this is necessary and how Tailwind's scanning behavior differs between PostCSS and Vite, see [Tailwind v4 with Angular in an Nx Monorepo](/blog/setup-tailwind-4-angular-nx-workspace).
|
||||
|
||||
### Tailwind CSS v3
|
||||
|
||||
For Tailwind CSS v3, the [`content`](https://v3.tailwindcss.com/docs/content-configuration) property should be configured to include glob patterns that cover your project and its dependencies:
|
||||
|
||||
-26
@@ -142,12 +142,6 @@ Type: `boolean`
|
||||
|
||||
Generate a `package.json` file for the bundle. Useful for Node applications.
|
||||
|
||||
##### runtimeDependencies
|
||||
|
||||
Type: `string[]`
|
||||
|
||||
Add runtime dependencies to the generated `package.json` file. Useful for Docker installs. Only works in conjunction with `generatePackageJson` option.
|
||||
|
||||
##### index
|
||||
|
||||
Type: `string`
|
||||
@@ -244,16 +238,6 @@ Type: `boolean`
|
||||
|
||||
Skip type checking. Default is `false`.
|
||||
|
||||
**`Deprecated`**
|
||||
|
||||
Use [`typeCheckOptions`](#typecheckoptions) instead. This option will be removed in Nx 24.
|
||||
|
||||
##### typeCheckOptions
|
||||
|
||||
Type: `boolean | { async: boolean }`
|
||||
|
||||
Configure type checking during the build. Set to `true` to enable type checking with default options (async: true). Set to `false` to disable type checking entirely. Use `{ async: true }` to run type checking in a separate process without blocking the build. Use `{ async: false }` to run type checking synchronously. Default is `{ async: true }`.
|
||||
|
||||
##### sourceMap
|
||||
|
||||
Type: `boolean | 'hidden'`
|
||||
@@ -418,16 +402,6 @@ Type: `boolean`
|
||||
|
||||
Disable type checks (useful to speed up builds).
|
||||
|
||||
**`Deprecated`**
|
||||
|
||||
Use [`typeCheckOptions`](#typecheckoptions-1) instead. This option will be removed in Nx 24.
|
||||
|
||||
##### typeCheckOptions
|
||||
|
||||
Type: `boolean | { async: boolean }`
|
||||
|
||||
Configure type checking during the build. Set to `true` to enable type checking with default options (async: true). Set to `false` to disable type checking entirely. Use `{ async: true }` to run type checking in a separate process without blocking the build. Use `{ async: false }` to run type checking synchronously. Default is `{ async: true }`.
|
||||
|
||||
#### Example
|
||||
|
||||
```js
|
||||
|
||||
+2
@@ -279,6 +279,7 @@ If you previously set `inferProjects: false` in your @nx-dotnet/core config, thi
|
||||
**Migration path:**
|
||||
|
||||
1. **If you disabled inference to exclude certain projects:**
|
||||
|
||||
- Use the `exclude` property in the plugin configuration:
|
||||
```json
|
||||
// nx.json
|
||||
@@ -293,6 +294,7 @@ If you previously set `inferProjects: false` in your @nx-dotnet/core config, thi
|
||||
```
|
||||
|
||||
2. **If you disabled inference to use explicit project.json files:**
|
||||
|
||||
- The new plugin will still detect your projects via `.csproj` files
|
||||
- You can keep `project.json` files to customize targets, but they're optional
|
||||
- Consider removing them to use the automatically inferred targets
|
||||
|
||||
@@ -57,17 +57,17 @@ export default [
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {},
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {},
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {},
|
||||
},
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -128,18 +128,18 @@ export default [
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {
|
||||
// This rule requires the TypeScript type checker to be present when it runs
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
},
|
||||
"@typescript-eslint/await-thenable": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {},
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {},
|
||||
},
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -219,21 +219,21 @@ export default [
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
// We set parserOptions.project for the project to allow TypeScript to create the type-checker behind the scenes when we run linting
|
||||
"parserOptions": {
|
||||
"project": ["apps/tuskdesk/tsconfig.*?.json"],
|
||||
"project": ["apps/tuskdesk/tsconfig.*?.json"]
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
},
|
||||
"@typescript-eslint/await-thenable": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {},
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {},
|
||||
},
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+23
-26
@@ -61,11 +61,11 @@ export default [
|
||||
"files": ["*.json"],
|
||||
"parser": "jsonc-eslint-parser",
|
||||
"rules": {
|
||||
"@nx/dependency-checks": "error",
|
||||
},
|
||||
},
|
||||
"@nx/dependency-checks": "error"
|
||||
}
|
||||
}
|
||||
// ... more ESLint overrides here
|
||||
],
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,11 +86,11 @@ Additionally, you need to adjust your `lintFilePatterns` to include the project'
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"libs/my-lib/**/*.{ts,tsx,js,jsx}",
|
||||
"libs/my-lib/package.json", // add this line
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"libs/my-lib/package.json" // add this line
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -119,7 +119,6 @@ export default [
|
||||
ignoredFiles: ['webpack.config.js', 'eslint.config.mjs'], // list of files that should be skipped for check
|
||||
includeTransitiveDependencies: true, // collect dependencies transitively from children
|
||||
useLocalPathsForWorkspaceDependencies: true, // toggle to disable
|
||||
peerDepsVersionStrategy: 'installed', // or 'workspace' to use workspace:* for peer dependencies
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -143,10 +142,9 @@ export default [
|
||||
"ignoredDependencies": ["lodash"], // these libs will be omitted from checks
|
||||
"ignoredFiles": ["webpack.config.js", "eslint.config.mjs"], // list of files that should be skipped for check
|
||||
"includeTransitiveDependencies": true, // collect dependencies transitively from children
|
||||
"useLocalPathsForWorkspaceDependencies": true, // toggle to disable
|
||||
"peerDepsVersionStrategy": "installed", // or 'workspace' to use workspace:* for peer dependencies
|
||||
},
|
||||
],
|
||||
"useLocalPathsForWorkspaceDependencies": true // toggle to disable
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -155,15 +153,14 @@ export default [
|
||||
|
||||
## Options
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
| ------------------------------------- | ---------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| buildTargets | _Array<string>_ | _["build"]_ | List of build target names |
|
||||
| checkMissingDependencies | _boolean_ | _true_ | Disable to skip checking for missing dependencies |
|
||||
| checkObsoleteDependencies | _boolean_ | _true_ | Disable to skip checking for unused dependencies |
|
||||
| checkVersionMismatches | _boolean_ | _true_ | Disable to skip checking if version specifier matches installed version |
|
||||
| ignoredDependencies | _Array<string>_ | _[]_ | List of dependencies to ignore for checks |
|
||||
| ignoredFiles | _Array<string>_ | N/A | List of files to ignore when collecting dependencies. The default value will be set based on the selected executor during the generation. |
|
||||
| includeTransitiveDependencies | _boolean_ | _false_ | Enable to collect dependencies of children projects |
|
||||
| useLocalPathsForWorkspaceDependencies | _boolean_ | _false_ | Set workspace dependencies as relative file:// paths. Useful for monorepos that link via file:// in package.json files. |
|
||||
| peerDepsVersionStrategy | _"installed" \| "workspace"_ | _"installed"_ | Strategy for version specifiers in peer dependencies. Use `"installed"` to use the installed version, or `"workspace"` to use `workspace:*` protocol for monorepo packages. |
|
||||
| runtimeHelpers | _Array<string>_ | _[]_ | List of helper packages used by the built output (e.g. `tslib` when using `tsc` and `importHelpers` is set to `true`). The rule already detects some of them in some scenarios, but this option can be used to detect them when it doesn't happen automatically. |
|
||||
| Property | Type | Default | Description |
|
||||
| ------------------------------------- | --------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| buildTargets | _Array<string>_ | _["build"]_ | List of build target names |
|
||||
| checkMissingDependencies | _boolean_ | _true_ | Disable to skip checking for missing dependencies |
|
||||
| checkObsoleteDependencies | _boolean_ | _true_ | Disable to skip checking for unused dependencies |
|
||||
| checkVersionMismatches | _boolean_ | _true_ | Disable to skip checking if version specifier matches installed version |
|
||||
| ignoredDependencies | _Array<string>_ | _[]_ | List of dependencies to ignore for checks |
|
||||
| ignoredFiles | _Array<string>_ | N/A | List of files to ignore when collecting dependencies. The default value will be set based on the selected executor during the generation. |
|
||||
| includeTransitiveDependencies | _boolean_ | _false_ | Enable to collect dependencies of children projects |
|
||||
| useLocalPathsForWorkspaceDependencies | _boolean_ | _false_ | Set workspace dependencies as relative file:// paths. Useful for monorepos that link via file:// in package.json files. |
|
||||
| runtimeHelpers | _Array<string>_ | _[]_ | List of helper packages used by the built output (e.g. `tslib` when using `tsc` and `importHelpers` is set to `true`). The rule already detects some of them in some scenarios, but this option can be used to detect them when it doesn't happen automatically. |
|
||||
|
||||
+5
-5
@@ -57,12 +57,12 @@ export default [
|
||||
"error",
|
||||
{
|
||||
// ...rule specific configuration
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
// ... more ESLint overrides here
|
||||
],
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+2
@@ -62,11 +62,13 @@ export default {
|
||||
The NxModuleFederationPlugin wraps and configures the Module Federation plugin from `@module-federation/enhanced` to provide a streamlined experience in Nx workspaces. Here's what the plugin does:
|
||||
|
||||
1. **Base Configuration**: It sets up essential Rspack configurations:
|
||||
|
||||
- Disables runtime chunking (`runtimeChunk: false`)
|
||||
- Sets a unique name for the output
|
||||
- Configures specific settings for server-side rendering when needed
|
||||
|
||||
2. **Module Federation Setup**: The plugin automatically:
|
||||
|
||||
- Configures the remote entry filename (`remoteEntry.js`)
|
||||
- Sets up exposed modules based on your configuration
|
||||
- Manages remote module connections
|
||||
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
---
|
||||
title: Using Tailwind CSS with Module Federation
|
||||
description: Learn how to configure Tailwind CSS so that classes used in remote applications are properly compiled by the host application.
|
||||
filter: 'type:Guides'
|
||||
---
|
||||
|
||||
When using [Tailwind CSS](https://tailwindcss.com/) with Module Federation, you may encounter an issue where Tailwind classes used in your remote applications don't render correctly. This guide explains why this happens and how to configure your workspace to resolve it.
|
||||
|
||||
## Understanding the Problem
|
||||
|
||||
Tailwind CSS uses a content scanning mechanism to determine which CSS classes to include in your final stylesheet. During the build process, Tailwind scans the files specified in your configuration and only generates CSS for the classes it finds. This is how Tailwind keeps your CSS bundle small by eliminating unused styles.
|
||||
|
||||
In a Module Federation architecture, the host and remote applications are built independently. When the host application builds, Tailwind only scans the host's source files—it has no knowledge of the classes used in remote applications. As a result, when remotes are loaded at runtime, any Tailwind classes they use that aren't also used in the host will be missing from the stylesheet.
|
||||
|
||||
{% aside type="note" title="This is expected behavior" %}
|
||||
This is not a bug in Nx or Module Federation. It's a fundamental aspect of how Tailwind's content scanning works combined with Module Federation's independent build model.
|
||||
{% /aside %}
|
||||
|
||||
## Configuring the Host Application
|
||||
|
||||
The solution is to configure your host application's Tailwind setup to include the source files from your remote applications. This ensures all Tailwind classes used across your federated application are compiled into the host's stylesheet.
|
||||
|
||||
### Tailwind CSS v4
|
||||
|
||||
For Tailwind CSS v4, use the [`@source` directive](https://tailwindcss.com/docs/detecting-classes-in-source-files) in your stylesheet to include remote application paths:
|
||||
|
||||
{% tabs %}
|
||||
{% tabitem label="React" %}
|
||||
|
||||
```css
|
||||
/* apps/shell/src/styles.css */
|
||||
@import 'tailwindcss';
|
||||
|
||||
/* Include shared libraries */
|
||||
@source "../../../libs";
|
||||
|
||||
/* Include remote applications */
|
||||
@source "../remote1/src";
|
||||
@source "../remote2/src";
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% tabitem label="Angular" %}
|
||||
|
||||
```css
|
||||
/* apps/shell/src/styles.css */
|
||||
@import 'tailwindcss';
|
||||
|
||||
/* Include shared libraries */
|
||||
@source "../../../libs";
|
||||
|
||||
/* Include remote applications */
|
||||
@source "../remote1/src";
|
||||
@source "../remote2/src";
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% /tabs %}
|
||||
|
||||
### Tailwind CSS v3
|
||||
|
||||
For Tailwind CSS v3, configure the [`content`](https://v3.tailwindcss.com/docs/content-configuration) array in your host's `tailwind.config.js` to include glob patterns for your remote applications:
|
||||
|
||||
{% tabs %}
|
||||
{% tabitem label="React" %}
|
||||
|
||||
```javascript
|
||||
// apps/shell/tailwind.config.js
|
||||
const { join } = require('path');
|
||||
|
||||
module.exports = {
|
||||
content: [
|
||||
join(__dirname, '{src,pages,components,app}/**/*.{ts,tsx,js,jsx}'),
|
||||
// Include shared libraries
|
||||
join(__dirname, '../../libs/**/*.{ts,tsx,js,jsx}'),
|
||||
// Include remote applications
|
||||
join(__dirname, '../remote1/src/**/*.{ts,tsx,js,jsx}'),
|
||||
join(__dirname, '../remote2/src/**/*.{ts,tsx,js,jsx}'),
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% tabitem label="Angular" %}
|
||||
|
||||
```javascript
|
||||
// apps/shell/tailwind.config.js
|
||||
const { join } = require('path');
|
||||
|
||||
module.exports = {
|
||||
content: [
|
||||
join(__dirname, 'src/**/*.{ts,html}'),
|
||||
// Include shared libraries
|
||||
join(__dirname, '../../libs/**/*.{ts,html}'),
|
||||
// Include remote applications
|
||||
join(__dirname, '../remote1/src/**/*.{ts,html}'),
|
||||
join(__dirname, '../remote2/src/**/*.{ts,html}'),
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% /tabs %}
|
||||
|
||||
Adjust the paths based on your workspace structure. If your remotes are in different directories, update the glob patterns accordingly.
|
||||
|
||||
## Shared Theme Extensions
|
||||
|
||||
If your remote applications use custom Tailwind theme extensions (such as custom colors, fonts, or spacing values), you need to ensure these are also defined in the host's Tailwind configuration. Otherwise, classes like `bg-brand-primary` or `text-custom-lg` won't generate any CSS.
|
||||
|
||||
Consider creating a shared Tailwind preset that all applications can extend:
|
||||
|
||||
```javascript
|
||||
// libs/shared/tailwind-preset/src/index.js
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
brand: {
|
||||
primary: '#3b82f6',
|
||||
secondary: '#10b981',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Then use this preset in both your host and remote configurations:
|
||||
|
||||
```javascript
|
||||
// apps/shell/tailwind.config.js
|
||||
const sharedPreset = require('../../libs/shared/tailwind-preset/src');
|
||||
|
||||
module.exports = {
|
||||
presets: [sharedPreset],
|
||||
content: [
|
||||
// ... your content configuration
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Using Tailwind CSS with Angular](/docs/technologies/angular/guides/using-tailwind-css-with-angular-projects)
|
||||
- [Using Tailwind CSS with React](/docs/technologies/react/guides/using-tailwind-css-in-react)
|
||||
- [Tailwind CSS v4 Source Detection](https://tailwindcss.com/docs/detecting-classes-in-source-files)
|
||||
- [Tailwind CSS v3 Content Configuration](https://v3.tailwindcss.com/docs/content-configuration)
|
||||
+2
-2
@@ -174,7 +174,7 @@ the `implicitDependencies` configuration.
|
||||
// apps/host/project.json
|
||||
{
|
||||
//...
|
||||
"implicitDependencies": ["about", "shop", "cart"],
|
||||
"implicitDependencies": ["about", "shop", "cart"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -424,7 +424,7 @@ the following line to the `host`'s project configuration.
|
||||
```jsonc title="apps/host/project.json"
|
||||
{
|
||||
//...
|
||||
"implicitDependencies": ["about", "shop", "cart"],
|
||||
"implicitDependencies": ["about", "shop", "cart"]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -64,11 +64,13 @@ export default {
|
||||
The NxModuleFederationPlugin wraps and configures the Module Federation plugin from `@module-federation/enhanced` to provide a streamlined experience in Nx workspaces. Here's what the plugin does:
|
||||
|
||||
1. **Base Configuration**: It sets up essential Rspack configurations:
|
||||
|
||||
- Disables runtime chunking (`runtimeChunk: false`)
|
||||
- Sets a unique name for the output
|
||||
- Configures specific settings for server-side rendering when needed
|
||||
|
||||
2. **Module Federation Setup**: The plugin automatically:
|
||||
|
||||
- Configures the remote entry filename (`remoteEntry.js`)
|
||||
- Sets up exposed modules based on your configuration
|
||||
- Manages remote module connections
|
||||
|
||||
@@ -14,7 +14,7 @@ We'll show you how to create a [React Router](https://reactrouter.com/home) appl
|
||||
|
||||
## Create Nx Workspace
|
||||
|
||||
```text {% frame="terminal" title="npx create-nx-workspace@latest acme" %}
|
||||
```text {% frame="terminal" title="npx create-nx-workspace@latest acme --preset=apps" %}
|
||||
|
||||
✔ Which stack do you want to use? · react
|
||||
✔ What framework would you like to use? · none
|
||||
|
||||
+2
-61
@@ -20,73 +20,14 @@ For the most up-to-date installation instructions, refer to the official Tailwin
|
||||
|
||||
### Tailwind CSS v4
|
||||
|
||||
Tailwind CSS v4 [automatically detects classes from source files](https://tailwindcss.com/docs/detecting-classes-in-source-files). However, with the Vite plugin, scanning only covers the app directory. This means classes from workspace libraries won't be included unless you explicitly add them.
|
||||
|
||||
Use `@source` directives to include your library dependencies:
|
||||
For Tailwind CSS v4, classes are [automatically detected from source files](https://tailwindcss.com/docs/detecting-classes-in-source-files). To register workspace libraries, add the following configuration to your stylesheet where you configure TailwindCSS.
|
||||
|
||||
```css
|
||||
// apps/myapp/src/styles.css
|
||||
@import 'tailwindcss';
|
||||
|
||||
@source "../../../libs/ui";
|
||||
@source "../../../libs/shared";
|
||||
@source "../../../libs";
|
||||
```
|
||||
|
||||
#### Automating @source directives
|
||||
|
||||
Manually maintaining `@source` directives is tedious and error-prone. Use [`@juristr/nx-tailwind-sync`](https://www.npmjs.com/package/@juristr/nx-tailwind-sync) to automate this based on your project's dependency graph.
|
||||
|
||||
Install the package:
|
||||
|
||||
```shell
|
||||
npm install @juristr/nx-tailwind-sync
|
||||
```
|
||||
|
||||
Register the sync generator for your application's `build` and `dev` targets:
|
||||
|
||||
{% tabs syncKey="project-config-file" %}
|
||||
{% tabitem label="package.json" %}
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "myapp",
|
||||
"nx": {
|
||||
"targets": {
|
||||
"build": {
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
},
|
||||
"dev": {
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% tabitem label="project.json" %}
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "myapp",
|
||||
"targets": {
|
||||
"build": {
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
},
|
||||
"dev": {
|
||||
"syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% /tabitem %}
|
||||
{% /tabs %}
|
||||
|
||||
When you run `nx build myapp` or `nx dev myapp`, the sync generator analyzes your dependency graph and updates your stylesheet with the correct `@source` directives automatically.
|
||||
|
||||
For more details on why this is necessary and how to build your own sync generator, see [Tailwind v4 with Vite in an NPM Workspace](/blog/setup-tailwind-4-npm-workspace).
|
||||
|
||||
### Tailwind CSS v3
|
||||
|
||||
For Tailwind CSS v3, the [`content`](https://v3.tailwindcss.com/docs/content-configuration) property should be configured to include glob patterns that cover your project and its dependencies:
|
||||
|
||||
@@ -200,7 +200,7 @@ In order to set different `baseURL` values for different environments you can pa
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
||||
const baseUrl =
|
||||
(process.env.BASE_URL ?? process.env.CI)
|
||||
process.env.BASE_URL ?? process.env.CI
|
||||
? 'https://some-staging-url.example.com'
|
||||
: 'http://localhost:4200';
|
||||
|
||||
|
||||
+4
-4
@@ -59,10 +59,10 @@ You can also configure the build using the `@nx/rollup:rollup` executor in your
|
||||
"main": "packages/my-awesome-lib/src/index.ts",
|
||||
"format": ["esm", "cjs"],
|
||||
"additionalEntryPoints": ["packages/my-awesome-lib/src/foo.ts"],
|
||||
"generateExportsField": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"generateExportsField": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+11
-11
@@ -50,13 +50,13 @@ If you're using the `@nx/js:tsc` executor, as of Nx 16.8, you can specify the `a
|
||||
"main": "packages/my-awesome-lib/src/index.ts",
|
||||
"additionalEntryPoints": [
|
||||
"packages/my-awesome-lib/src/foo.ts",
|
||||
"packages/my-awesome-lib/src/bar.ts",
|
||||
"packages/my-awesome-lib/src/bar.ts"
|
||||
],
|
||||
"generateExportsField": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"generateExportsField": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -74,12 +74,12 @@ If you're using the `@nx/js:tsc` executor, as of Nx 16.8, you can specify the `a
|
||||
"main": "packages/my-awesome-lib/src/index.ts",
|
||||
"additionalEntryPoints": [
|
||||
"packages/my-awesome-lib/src/foo.ts",
|
||||
"packages/my-awesome-lib/src/bar.ts",
|
||||
"packages/my-awesome-lib/src/bar.ts"
|
||||
],
|
||||
"generateExportsField": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"generateExportsField": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+26
-26
@@ -125,9 +125,9 @@ Note: Before you delete the `paths` property, copy the project paths for use as
|
||||
// ...
|
||||
"paths": {
|
||||
"@myorg/utils": ["libs/utils/src/index.ts"],
|
||||
"@myorg/ui": ["libs/ui/src/index.ts"],
|
||||
},
|
||||
},
|
||||
"@myorg/ui": ["libs/ui/src/index.ts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -144,8 +144,8 @@ Note: Before you delete the `paths` property, copy the project paths for use as
|
||||
// Delete the paths property
|
||||
// Other options...
|
||||
"allowJs": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
},
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -161,7 +161,7 @@ The root `tsconfig.json` file should extend `tsconfig.base.json` and not include
|
||||
// tsconfig.json
|
||||
{
|
||||
"extends": "./tsconfig.base.json",
|
||||
"files": [], // intentionally empty
|
||||
"files": [] // intentionally empty
|
||||
}
|
||||
```
|
||||
|
||||
@@ -177,13 +177,13 @@ The root `tsconfig.json` file should extend `tsconfig.base.json` and not include
|
||||
"references": [
|
||||
// All projects in the repository
|
||||
{
|
||||
"path": "./libs/utils",
|
||||
"path": "./libs/utils"
|
||||
},
|
||||
{
|
||||
"path": "./libs/ui",
|
||||
},
|
||||
"path": "./libs/ui"
|
||||
}
|
||||
// Future generated projects will automatically be added here by the generator
|
||||
],
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -202,17 +202,17 @@ Make sure that the `@nx/js` plugin is installed in your repository and `@nx/js/t
|
||||
"plugin": "@nx/js/typescript",
|
||||
"options": {
|
||||
"typecheck": {
|
||||
"targetName": "typecheck",
|
||||
"targetName": "typecheck"
|
||||
},
|
||||
"build": {
|
||||
"targetName": "build",
|
||||
"configName": "tsconfig.lib.json",
|
||||
"buildDepsName": "build-deps",
|
||||
"watchDepsName": "watch-deps",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
"watchDepsName": "watch-deps"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -293,12 +293,12 @@ The `tsconfig.json` file's purpose is to provide your IDE with `references` to t
|
||||
// UPDATED BY NX SYNC
|
||||
// This project's other tsconfig.*.json files
|
||||
{
|
||||
"path": "./tsconfig.lib.json",
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json",
|
||||
},
|
||||
],
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -314,7 +314,7 @@ If there are a lot of shared `compilerOptions` between `tsconfig.lib.json` and `
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
// outDir should be local to the project and not in the same folder as any other tsconfig.*.json
|
||||
"outDir": "./out-tsc/lib",
|
||||
"outDir": "./out-tsc/lib"
|
||||
// Any overrides
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
@@ -324,7 +324,7 @@ If there are a lot of shared `compilerOptions` between `tsconfig.lib.json` and `
|
||||
"references": [
|
||||
// tsconfig.lib.json files for project dependencies
|
||||
// UPDATED BY NX SYNC
|
||||
],
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -340,7 +340,7 @@ The project's `tsconfig.spec.json` does not need to reference project dependenci
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
// outDir should be local to the project and not in the same folder as any other tsconfig.*.json
|
||||
"outDir": "./out-tsc/spec",
|
||||
"outDir": "./out-tsc/spec"
|
||||
// Any overrides
|
||||
},
|
||||
"include": [
|
||||
@@ -349,9 +349,9 @@ The project's `tsconfig.spec.json` does not need to reference project dependenci
|
||||
"references": [
|
||||
// tsconfig.lib.json for this project
|
||||
{
|
||||
"path": "./tsconfig.lib.json",
|
||||
},
|
||||
],
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user