Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 070e9612c8 | |||
| 518b0cbfa5 | |||
| a95a60cfe5 | |||
| e7bcbe95d5 | |||
| 8fa50e7f0d | |||
| 4eb3267100 | |||
| 4f3118d5f8 | |||
| 15c67cf45f | |||
| 442058a27b | |||
| 2057df57ed | |||
| 7ed00c0dc9 | |||
| ebac21df16 | |||
| 0ca030f9d4 | |||
| 883476e7e3 | |||
| 2d872a34ee | |||
| ada8be473d | |||
| 121d9973a8 | |||
| 5b034965d8 | |||
| 7da48d6471 | |||
| 1c323131f8 | |||
| 648129fc48 | |||
| 7ba707e7b3 | |||
| 00e970a0bb | |||
| e4f7e56e3c | |||
| e8acab6ae0 | |||
| 2c0b5d3c8e | |||
| 30b5043a4c | |||
| 04cf098d59 | |||
| 437bad4aac | |||
| d428eec060 | |||
| c698b1ef9c | |||
| 8e6c00719b | |||
| 6678c74f24 | |||
| bf10eae48e | |||
| 61ff25fc08 | |||
| 1407152b70 | |||
| 2b98830b3a | |||
| 04bd26f6c0 | |||
| e57df6f6be | |||
| a5d20030db | |||
| b992e2586b | |||
| bd78ac25b8 | |||
| d2a9cbc97d | |||
| 977e72b68c | |||
| 5382c8af65 | |||
| 2986a02dc9 | |||
| 914b1cc1db | |||
| 651f16cdb9 | |||
| 9faafe5d7d | |||
| 30f5a52d96 | |||
| e8647df08a | |||
| 8b11d8bfe5 | |||
| 6fcb310e54 | |||
| 320709f66f | |||
| a58b7aba8a | |||
| 4fe4fe95fa | |||
| 7a73e8a006 | |||
| 811bac5cf7 | |||
| 6d40b6a6ca | |||
| 321a63aac3 | |||
| 0ae4925e43 | |||
| 09ebf5f2da | |||
| f156ea932d | |||
| 7de6a7b0d7 | |||
| 1738d79ca5 | |||
| 44e7b41c4f | |||
| 202b49bdbe | |||
| 32341d5efc | |||
| 9cbd476193 | |||
| c35862d4b8 | |||
| c02719d2df | |||
| 4fc52cf836 | |||
| 2fc1945615 | |||
| 63cb68d1b6 | |||
| b063fcd3b1 | |||
| cd361ef0ef | |||
| 82169ace03 | |||
| 75a69d93d0 | |||
| 4367352a0a | |||
| 5bfcc77b74 | |||
| b9221bfe5d | |||
| 251959c6b0 | |||
| e643899a57 | |||
| 46e5dcefb0 | |||
| a90de969ab | |||
| 639d748b70 |
@@ -8,8 +8,12 @@ on:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
NX_CLOUD_ACCESS_TOKEN: OWViNjcxNmUtYzRmNC00YzBjLWFhNGEtNzc0OTYxZDYwNmEwfHJlYWQtd3JpdGU=
|
||||
|
||||
jobs:
|
||||
main-linux:
|
||||
@@ -22,10 +26,8 @@ jobs:
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_CI_EXECUTION_ENV: 'linux'
|
||||
NX_CLOUD_DTE_V2: 'true'
|
||||
NX_CLOUD_DTE_SUMMARY: 'true'
|
||||
NX_CLOUD_NO_TIMEOUTS: 'true'
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -35,11 +37,13 @@ jobs:
|
||||
- name: Fetch Master
|
||||
run: git fetch origin master:master
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
|
||||
|
||||
- name: Set SHAs
|
||||
uses: nrwl/nx-set-shas@v4
|
||||
|
||||
with:
|
||||
main-branch-name: 'master'
|
||||
|
||||
- name: Start CI Run
|
||||
run: npx nx-cloud@next start-ci-run --distribute-on="./.nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e"
|
||||
|
||||
@@ -85,7 +89,7 @@ jobs:
|
||||
pnpm nx run-many -t check-imports check-commit check-lock-files check-codeowners --parallel=1 --no-dte &
|
||||
pids+=($!)
|
||||
|
||||
pnpm nx affected --targets=lint,test,build,e2e,e2e-ci --base=$NX_BASE --head=$NX_HEAD --parallel=3 &
|
||||
pnpm nx affected --targets=lint,test,build,e2e,e2e-ci --base=$NX_BASE --head=$NX_HEAD &
|
||||
pids+=($!)
|
||||
|
||||
for pid in "${pids[@]}"; do
|
||||
@@ -149,7 +153,9 @@ jobs:
|
||||
|
||||
- name: Set SHAs
|
||||
uses: nrwl/nx-set-shas@v4
|
||||
|
||||
with:
|
||||
main-branch-name: 'master'
|
||||
|
||||
- name: Run E2E Tests for macOS
|
||||
run: |
|
||||
HAS_CHANGED=$(node ./scripts/check-react-native-changes.js $NX_BASE $NX_HEAD);
|
||||
@@ -157,4 +163,43 @@ jobs:
|
||||
pnpm nx affected -t e2e-macos-local --parallel=1 --base=$NX_BASE --head=$NX_HEAD
|
||||
else
|
||||
echo "Skip E2E tests for macOS as there are no changes in React Native projects."
|
||||
fi
|
||||
fi
|
||||
|
||||
benchmarks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Fetch Master
|
||||
run: git fetch origin master:master
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- name: Set SHAs
|
||||
uses: nrwl/nx-set-shas@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 9.8.0
|
||||
run_install: false
|
||||
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Run benchmarks
|
||||
uses: CodSpeedHQ/action@v3
|
||||
with:
|
||||
run: "pnpm exec nx run-many -t benchmark"
|
||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||
@@ -2,6 +2,7 @@ node_modules
|
||||
/.idea
|
||||
/.fleet
|
||||
/.vscode
|
||||
/.cursor
|
||||
dist
|
||||
/build
|
||||
/coverage
|
||||
|
||||
@@ -7,8 +7,16 @@ assignment-rules:
|
||||
- build*
|
||||
run-on:
|
||||
- agent: linux-extra-large
|
||||
parallelism: 1
|
||||
|
||||
- targets:
|
||||
- lint
|
||||
run-on:
|
||||
- agent: linux-medium
|
||||
parallelism: 6
|
||||
|
||||
- targets:
|
||||
- '*'
|
||||
run-on:
|
||||
- agent: linux-medium
|
||||
- agent: linux-medium
|
||||
parallelism: 3
|
||||
|
||||
@@ -19,9 +19,7 @@ While speed is of major importance, developer ergonomics shouldn't be left behin
|
||||
|
||||
## Update (Aug 2023): Want a non-monorepo setup?
|
||||
|
||||
This article walks you through how to setup a new Nx monorepo workspace with React. If you rather prefer starting with a single-project setup (also named "standalone") then you might want to have a look at this tutorial (including video):
|
||||
|
||||
[/getting-started/tutorials/react-standalone-tutorial](/getting-started/tutorials/react-standalone-tutorial)
|
||||
This article walks you through how to setup a new Nx monorepo workspace with React. If you rather prefer starting with a single-project setup (also named "standalone") then you might want to have a look at the standalone tutorial (including video).
|
||||
|
||||
## Why use a devtool CLI?
|
||||
|
||||
|
||||
@@ -181,7 +181,6 @@ It is an ongoing process, and we have a lot of content to cover! We follow the [
|
||||
|
||||
Besides the two new [package-based](/getting-started/tutorials/typescript-packages-tutorial) and [integrated style tutorials](/getting-started/tutorials/react-monorepo-tutorial) we also have two brand new reworked tutorials
|
||||
|
||||
- [/getting-started/tutorials/react-standalone-tutorial](/getting-started/tutorials/react-standalone-tutorial)
|
||||
- [/getting-started/tutorials](/getting-started/tutorials)
|
||||
|
||||
Stay tuned for more updates to come.
|
||||
|
||||
@@ -39,7 +39,7 @@ And so did also [Fireship](https://youtu.be/2OTq15A5s0Y) and ultimately [Dan Abr
|
||||
|
||||
Code generators speed up such configuration tasks. They are valuable for scaffolding the initial project structure and adding new features to the app setup, such as Tailwind.
|
||||
|
||||
Nx has such generators. To use them, you need an Nx-based React setup. If you're starting new, you can create an [Nx Standalone React project](/getting-started/tutorials/react-standalone-tutorial) easily using the following command
|
||||
Nx has such generators. To use them, you need an Nx-based React setup. If you're starting new, you can create an Nx Standalone React project easily using the following command
|
||||
|
||||
```shell
|
||||
$ npx create-nx-workspace reactapp --preset=react-standalone
|
||||
@@ -59,7 +59,7 @@ You can pass `--vite=false` if you still want to keep the Webpack configuration
|
||||
|
||||
## Generating a Tailwind Setup
|
||||
|
||||
Once you have a [Nx-based React](/getting-started/tutorials/react-standalone-tutorial) setup, adding Tailwind is as easy as running:
|
||||
Once you have a [Nx-based React](/getting-started/tutorials/react-monorepo-tutorial) setup, adding Tailwind is as easy as running:
|
||||
|
||||
```shell
|
||||
$ npx nx g @nrwl/react:setup-tailwind
|
||||
@@ -79,7 +79,6 @@ You'll get
|
||||
|
||||
You should be all setup and ready now! Here are some related resources to explore:
|
||||
|
||||
- [Nx docs: React Standalone tutorial](/getting-started/tutorials/react-standalone-tutorial)
|
||||
- [Nx docs: React Monorepo tutorial](/getting-started/tutorials/react-monorepo-tutorial)
|
||||
- [Youtube: Is CRA Dead](https://youtu.be/fkTz6KJxhhE)
|
||||
- [Nx docs: Migrate CRA to React and Vite](/recipes/adopting-nx/adding-to-existing-project)
|
||||
|
||||
@@ -636,7 +636,7 @@ This should give you a good insight into how to get started. But there's more to
|
||||
- We could also include "[executors](/extending-nx/recipes/local-executors)", which are wrappers around tasks to abstract the lower-level details of it
|
||||
- etc.
|
||||
|
||||
Now clearly this was a simple example of how you could build your own CRA using Nx. If you want to see a real-world React setup powered by Nx, check out our React Tutorial: [/getting-started/tutorials/react-standalone-tutorial](/getting-started/tutorials/react-standalone-tutorial)
|
||||
Now clearly this was a simple example of how you could build your own CRA using Nx. If you want to see a real-world React setup powered by Nx, check out our React Tutorial: [/getting-started/tutorials/react-monorepo-tutorial](/getting-started/tutorials/react-monorepo-tutorial)
|
||||
|
||||
## Learn more
|
||||
|
||||
|
||||
@@ -54,8 +54,6 @@ And you'll have access to Nx generators so that you can generate Vue application
|
||||
|
||||
We're very excited for this support to land, and we're eager to get it into our user's hands and see what Nx can do to help Vue developers so we can continue to refine our support and make Vue with Nx an excellent developer experience.
|
||||
|
||||
If you're eager to learn more, make sure to check out our new [Vue standalone tutorial](/getting-started/tutorials/vue-standalone-tutorial).
|
||||
|
||||
## Enhancements to Module Federation Support
|
||||
|
||||
Nx already had great support for Module Federation — Nx 17 improves on this support:
|
||||
@@ -236,7 +234,7 @@ For more [checkout our API docs](/nx-api/nx/documents/release), and be sure to c
|
||||
|
||||
At Nx, we're OBSESSED with building a better, more robust experience for our developers. Towards this end, we're now in [v2 of our Project Inference API](/extending-nx/recipes/project-graph-plugins).
|
||||
|
||||
This API is a way of extending the Nx project graph, which can be particularly helpful for extending Nx to support other languages, allowing Nx to determine where to find and draw boundaries around projects in your workspace. A great example is our very own [Vue plugin](/getting-started/tutorials/vue-standalone-tutorial).
|
||||
This API is a way of extending the Nx project graph, which can be particularly helpful for extending Nx to support other languages, allowing Nx to determine where to find and draw boundaries around projects in your workspace. A great example is our very own [Vue plugin](/nx-api/vue).
|
||||
|
||||
Interestingly, v2 includes support for dynamic targets as well. This opens up exciting new doors to reducing configuration, and we hope to expand on this to better support our first-party plugins in the near future.
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ And you'll then have access to Nx generators so you can create Vue applications,
|
||||
|
||||

|
||||
|
||||
Checkout out our [Vue standalone tutorial](/getting-started/tutorials/vue-standalone-tutorial) for more, as well as our [Vue API docs](/nx-api/vue), and stay tuned as Nx prepares to offer more Vue support (including support for [Nuxt](https://nuxt.com/), a full-stack framework built around Vue) in the near future!
|
||||
Checkout out our [Vue API docs](/nx-api/vue), and stay tuned as Nx prepares to offer more Vue support (including support for [Nuxt](https://nuxt.com/), a full-stack framework built around Vue) in the near future!
|
||||
|
||||
### Extending Nx: Local Generators, Build your Own CLI, Verdaccio Support
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
title: 'Monorepos: the Benefits, Challenges, and Importance of Tooling Support '
|
||||
description: 'Learn how monorepos and better tooling can help you overcome challenges in software development like scalability, maintenance, communication, and cost.'
|
||||
date: 2024-01-24
|
||||
slug: 'monorepos-the-benefits-challenges-and-importance-of-tooling-support'
|
||||
authors: ['Juri Strumpflohner']
|
||||
tags: [webinar]
|
||||
|
||||
@@ -21,9 +21,7 @@ As you can see `@tuskdesign/forms` relies on `@tuskdesign/buttons` and as such h
|
||||
|
||||
---
|
||||
|
||||
**Prefer a video?**
|
||||
|
||||
{% youtube src="https://www.youtube.com/embed/KjZKFGu3_9I?si=L-8oRzy-hV-WF_pS" title="Versioning and Releasing Packages in a Monorepo" /%}
|
||||
{% link-card title="Free Course: Versioning and Releasing NPM packages with Nx" type="external" url="https://www.epicweb.dev/tutorials/versioning-and-releasing-npm-packages-with-nx" icon="/documentation/shared/images/nx-release-course-logo.webp" /%}
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
title: "Nx Agents Walkthrough:
|
||||
Effortlessly Fast CI Built for Monorepos"
|
||||
description: "Learn how you can streamline your existing CI config to its absolute simplest form, reducing CI times from 30 minutes to ~5 minutes with Nx Agents. "
|
||||
slug: 'nx-agents-walkthrougheffortlessly-fast-ci-built-for-monorepos'
|
||||
title: 'Nx Agents Walkthrough: Effortlessly Fast CI Built for Monorepos'
|
||||
description: 'Learn how you can streamline your existing CI config to its absolute simplest form, reducing CI times from 30 minutes to ~5 minutes with Nx Agents. '
|
||||
date: 2024-03-11
|
||||
slug: 'nx-agents-walkthrough-effortlessly-fast-ci-built-for-monorepos'
|
||||
authors: ['Rareș Matei']
|
||||
tags: [webinar]
|
||||
cover_image: /blog/images/2024-03-11/march-webinar.png
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
title: 'Making the Argument for Monorepos'
|
||||
description: 'Trying to convince your colleagues to use a monorepo? Already using a monorepo and need to justify that decision? Check out this webinar to learn 7 essential reasons for using monorepos and bust a few myths and misconceptions along the way.'
|
||||
description: 'Trying to convince your colleagues to use a monorepo? Already using a monorepo and need to justify that decision? Check out this webinar to learn 7 essential reasons for using monorepos and bust a few myths and misconceptions along the way.'
|
||||
date: 2024-04-17
|
||||
slug: 'making-the-argument-for-monorepos'
|
||||
authors: ['Miroslav Jonaš']
|
||||
tags: [webinar]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
title: "Monorepos and CI can be a Mess - Here's How Nx and Nx Cloud Fixed It"
|
||||
description: "Continuous Integration (CI) in monorepos can be notoriously slow and unreliable, quickly become a bottleneck for scaling monorepos.
|
||||
Learn how Nx and Nx Cloud's new task-based approach ensures fast, resilient, and efficient CI for your monorepo projects."
|
||||
date: 2024-06-26
|
||||
slug: 'monorepos-and-ci-can-be-a-mess-heres-how-nx-and-nx-cloud-fixed-it'
|
||||
authors: ['Juri Strumpflohner']
|
||||
tags: [webinar]
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
---
|
||||
title: 'Nx Cloud: Scale Your CI and Team with Ease'
|
||||
description: 'Learn how you can attain fast, reliable CI and better coordination across your technical organization with Nx Cloud, and see our new multi-workspace features for organizational scaling in action.'
|
||||
date: 2025-01-22
|
||||
slug: 'nx-cloud-scale-your-ci-and-team-with-ease'
|
||||
authors: ['Nicole Oliver', 'Rareș Matei', 'James Henry']
|
||||
tags: [webinar]
|
||||
cover_image: /blog/images/2025-01-22/Jan-webinar-image.png
|
||||
time: 1-2pm ET/6-7pm UTC
|
||||
status: Past - Gated
|
||||
registrationUrl: https://go.nx.dev/jan2025-webinar
|
||||
---
|
||||
|
||||
**Jan 22, 2025 - 1-2pm ET/6-7pm UTC**
|
||||
|
||||
Presented by Nicole Oliver, Rareș Matei, and James Henry
|
||||
|
||||
Learn how you can attain fast, reliable CI and better coordination across your technical organization with Nx Cloud, and see our new multi-workspace features for organizational scaling in action.
|
||||
|
||||
@@ -0,0 +1,719 @@
|
||||
---
|
||||
title: 'Using Apollo GraphQL in an Nx Workspace'
|
||||
slug: 'using-apollo-graphql-in-an-nx-workspace'
|
||||
authors: ['Philip Fulcher']
|
||||
cover_image: '/blog/images/2025-02-21/header.avif'
|
||||
tags: [nx]
|
||||
description: 'Learn how to create an Nx workspace that provides a GraphQL API via Apollo Server, a React frontend, and code generated by GraphQL Codegen to save time on development.'
|
||||
---
|
||||
|
||||
Because of the Nx's robust support for a diverse ecosystem of JavaScript development, it enables you to build your entire full-stack application in a single repo. This allows you to share code and interfaces between your frontend and backend and acts as a multiplier on your development velocity.
|
||||
|
||||
[GraphQL](https://graphql.org/) is a query language for your API. Because of its typed schema definition, it’s a great candidate for defining the contract between your API and its consumers. By using smart tools to generate code based on that schema, you can save yourself a lot of time and enforce better cooperation between your frontend and backend.
|
||||
|
||||
In this article, you will build a simple GraphQL API that tracks some information about Lego sets. You’ll create this API using Apollo Server, and it will be consumed by a React application. You’ll have this all inside of an Nx Workspace in a single repository.
|
||||
|
||||
In this article, you’ll learn how to:
|
||||
|
||||
- Create an Nx workspace for both frontend and backend applications
|
||||
- Create a GraphQL API using [Apollo Server](https://www.apollographql.com/docs/apollo-server)
|
||||
- Generate frontend code and backend resolver types based on your GraphQL schema using [GraphQL Codegen](https://the-guild.dev/graphql/codegen)
|
||||
- Create a [React](https://react.dev/) application to consume your GraphQL API
|
||||
|
||||
{% callout type="note" title="Minimal configuration" %}
|
||||
When given the option to enable another tool, like linting or testing, we're going to decline. This keeps this article focussed on GraphQL instead of having lint and test configs in the example. As you progress, feel free to enable these additional options if you'd like, especially if you're adding to an existing workspace that has those tools enabled.
|
||||
{% /callout %}
|
||||
|
||||
An example repo with all the work you’ll be doing here can be found in [our Nx Recipes repo](https://github.com/nrwl/nx-recipes/tree/main/apollo-graphql)
|
||||
|
||||
## Create a new workspace
|
||||
|
||||
Start by creating an Nx workspace:
|
||||
|
||||
```shell
|
||||
npx create-nx-workspace@latest --preset=node-monorepo nx-apollo
|
||||
```
|
||||
|
||||
When prompted, answer the prompts as follows:
|
||||
|
||||
```shell
|
||||
❯ npx create-nx-workspace@latest --preset node nx-apollo
|
||||
|
||||
NX Let's create a new workspace [https://nx.dev/getting-started/intro]
|
||||
|
||||
✔ Application name · api
|
||||
✔ What framework should be used? · none
|
||||
✔ Would you like to generate a Dockerfile? [https://docs.docker.com/] · No
|
||||
✔ Which CI provider would you like to use? · skip
|
||||
✔ Would you like remote caching to make your build faster? · skip
|
||||
```
|
||||
|
||||
## Create GraphQL schema and project
|
||||
|
||||
We want to generate model types from our schema that can be used by other projects in our workspace, so we'll start by creating a new project:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/js:library --directory=libs/models-graphql models-graphql
|
||||
```
|
||||
|
||||
When prompted, answer the prompts as follows:
|
||||
|
||||
```shell
|
||||
❯ npx nx g @nx/js:library --directory=libs/models-graphql models-graphql
|
||||
|
||||
NX Generating @nx/js:library
|
||||
|
||||
✔ Which bundler would you like to use to build the library? Choose 'none' to skip build setup. · none
|
||||
✔ Which linter would you like to use? · none
|
||||
✔ Which unit test runner would you like to use? · none
|
||||
```
|
||||
|
||||
{% callout type="note" title="Why do I need a separate project?" %}
|
||||
When you have your GraphQL schema and generated models in a separate project, other projects can depend on it. This ensures that all projects are using the same version of the schema and models. This exemplifies the "modulith" structure for monorepos. [Read more](/blog/virtuous-cycle-of-workspace-structure)
|
||||
{% /callout %}
|
||||
|
||||
You need a GraphQL schema to create the API, so write a very simple one with a single query and a single mutation. Create a file named `schema.graphql` in the new `models-graphql` project:
|
||||
|
||||
```graphql {% fileName="libs/models-graphql/src/lib/schema.graphql" %}
|
||||
type Set {
|
||||
id: Int!
|
||||
name: String
|
||||
year: Int
|
||||
numParts: Int
|
||||
}
|
||||
|
||||
type Query {
|
||||
allSets: [Set]
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
addSet(name: String, year: String, numParts: Int): Set
|
||||
}
|
||||
```
|
||||
|
||||
To start generating our models from this schema, we'll use [GraphQl Codegen](https://the-guild.dev/graphql/codegen). Install the packages needed:
|
||||
|
||||
```shell
|
||||
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers @graphql-codegen/typescript-react-apollo
|
||||
```
|
||||
|
||||
GraphQL Codegen is controlled by a configuration file named `codegen.ts` in each project that needs it. Create one for `models-graphql`:
|
||||
|
||||
```typescript {% fileName="libs/models-graphql/codegen.ts" %}
|
||||
import type { CodegenConfig } from '@graphql-codegen/cli';
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: 'libs/models-graphql/src/lib/schema.graphql',
|
||||
generates: {
|
||||
'libs/models-graphql/src/lib/__generated__/models.ts': {
|
||||
plugins: ['typescript'],
|
||||
config: {
|
||||
avoidOptionals: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
To run GraphqlQL Codegen, we need a target added to our project. Add this to the `project.json` for `models-graphql`:
|
||||
|
||||
```json {% fileName="libs/models-graphql/project.json" %}
|
||||
"targets": {
|
||||
"codegen": {
|
||||
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Run the `codegen` task to generate our new models:
|
||||
|
||||
```shell
|
||||
npx nx codegen models-graphql
|
||||
```
|
||||
|
||||
You should see the new models created in the `__generated__` directory in `models-graphql`. To use them outside the project, export them from the `index.ts`:
|
||||
|
||||
```typescript {% fileName="libs/models-graphql/src/index.ts" %}
|
||||
export * from './lib/__generated__/models';
|
||||
```
|
||||
|
||||
## Create GraphQL API
|
||||
|
||||
Use Apollo Server to create your GraphQL api. Start by installing the GraphQL modules needed for Apollo
|
||||
|
||||
```shell
|
||||
npm install @apollo/server graphql
|
||||
```
|
||||
|
||||
The workspace was generated with a Node application for us, but we need to make some small changes to support ESM for Apollo Server. First, change these compiler options in `tsconfig.app.json`:
|
||||
|
||||
```json {% fileName="apps/api/tsconfig.app.json" %}
|
||||
"compilerOptions": {
|
||||
"lib": ["es2020"],
|
||||
"target": "es2020",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
And change the `build` target config in `project.json`:
|
||||
|
||||
```json {% fileName="apps/api/project.json" %}
|
||||
"targets": {
|
||||
"build": {
|
||||
...
|
||||
"options": {
|
||||
...
|
||||
"format": ["esm"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
GraphQl Codegen has already created our models for our GraphQL schema, but it can also generate the resolver types we'll want to implement in Apollo Server. Like before, create a `codegen.ts` in the `api` application:
|
||||
|
||||
```typescript {% fileName="apps/api/codegen.ts" %}
|
||||
import type { CodegenConfig } from '@graphql-codegen/cli';
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: 'libs/models-graphql/src/lib/schema.graphql',
|
||||
generates: {
|
||||
'apps/api/src/__generated__/resolvers.ts': {
|
||||
plugins: ['add', 'typescript-resolvers'],
|
||||
config: {
|
||||
useIndexSignature: true,
|
||||
content: 'import * as types from "@nx-apollo/models-graphql"',
|
||||
namespacedImportName: 'types',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
And add the task to our targets:
|
||||
|
||||
```json {% fileName="apps/api/project.json" %}
|
||||
"targets": {
|
||||
"codegen": {
|
||||
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And run the task:
|
||||
|
||||
```shell
|
||||
npx nx codegen api
|
||||
```
|
||||
|
||||
And now there should be resolver types in the `__generated__` directory. We're ready to put create our Apollo Server application. Replace the contents of `main.ts` with this:
|
||||
|
||||
```typescript {% fileName="apps/api/src/main.ts" %}
|
||||
import { ApolloServer } from '@apollo/server';
|
||||
import { startStandaloneServer } from '@apollo/server/standalone';
|
||||
import { Set } from '@nx-apollo/models-graphql';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { Resolvers } from './__generated__/resolvers';
|
||||
|
||||
// Note: this uses a path relative to the project's
|
||||
// root directory, which is the current working directory
|
||||
// if the server is executed using `npm run`.
|
||||
const typeDefs = readFileSync(
|
||||
join('libs/models-graphql/src/lib', 'schema.graphql'),
|
||||
{ encoding: 'utf-8' }
|
||||
);
|
||||
|
||||
const sets: Set[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Voltron',
|
||||
numParts: 2300,
|
||||
year: '2019',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Ship in a Bottle',
|
||||
numParts: 900,
|
||||
year: '2019',
|
||||
},
|
||||
];
|
||||
|
||||
// Resolvers define how to fetch the types defined in your schema.
|
||||
// This resolver retrieves books from the "books" array above.
|
||||
const resolvers: Resolvers = {
|
||||
Query: {
|
||||
allSets: () => sets,
|
||||
},
|
||||
Mutation: {
|
||||
addSet: (parent, args) => {
|
||||
const newSet = {
|
||||
id: sets.length + 1,
|
||||
name: args.name,
|
||||
year: args.year,
|
||||
numParts: +args.numParts,
|
||||
};
|
||||
|
||||
sets.push(newSet);
|
||||
|
||||
return newSet;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// The ApolloServer constructor requires two parameters: your schema
|
||||
// definition and your set of resolvers.
|
||||
const server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
|
||||
// Passing an ApolloServer instance to the `startStandaloneServer` function:
|
||||
// 1. creates an Express app
|
||||
// 2. installs your ApolloServer instance as middleware
|
||||
// 3. prepares your app to handle incoming requests
|
||||
const { url } = await startStandaloneServer(server, {
|
||||
listen: { port: 4000 },
|
||||
});
|
||||
|
||||
console.log(`🚀 Server ready at: ${url}`);
|
||||
```
|
||||
|
||||
This is already enough to see some progress when you run the `api` application.
|
||||
|
||||
```shell
|
||||
npx nx serve api
|
||||
```
|
||||
|
||||
When the application is running, bring up the GraphQL Playground in your browser at [http://localhost:4000/](http://localhost:4000/)
|
||||
|
||||
Here you can inspect your GraphQL schema as well as submit queries and mutations.
|
||||
|
||||
This is a very simple resolver that holds data in memory. It returns the current contents of the sets array for the `allSets` query and allows users to add a new set using the `addSet` mutation. Add this resolver to the providers array in your app module:
|
||||
|
||||
Go back to your GraphQL Playground and see if your queries return any data now. Try a query and a mutation:
|
||||
|
||||
```graphql
|
||||
query allSets {
|
||||
allSets {
|
||||
id
|
||||
name
|
||||
numParts
|
||||
}
|
||||
}
|
||||
|
||||
mutation addSet {
|
||||
addSet(name: "My New Set", numParts: 200, year: "2020") {
|
||||
id
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now that the API is working, you’re ready to build a frontend to access this.
|
||||
|
||||
## Add React frontend
|
||||
|
||||
Start by adding a React app to your workspace using the `@nx/react` plugin:
|
||||
|
||||
```shell
|
||||
npx nx add @nx/react
|
||||
```
|
||||
|
||||
Create the React app using the generator:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react:app --directory=apps/frontend frontend
|
||||
```
|
||||
|
||||
When prompted, answer the prompts as follows:
|
||||
|
||||
```shell
|
||||
❯ npx nx g @nx/react:app --directory=apps/frontend frontend
|
||||
|
||||
NX Generating @nx/react:application
|
||||
|
||||
✔ Which stylesheet format would you like to use? · tailwind
|
||||
✔ Would you like to add React Router to this application? (y/N) · false
|
||||
✔ Which bundler do you want to use to build the application? · vite
|
||||
✔ Which linter would you like to use? · none
|
||||
✔ What unit test runner should be used? · none
|
||||
✔ Which E2E test runner would you like to use? · none
|
||||
```
|
||||
|
||||
We use Tailwind styles here for convenience. It will allow us to add some simple styles to our app without adding CSS files and importing them.
|
||||
|
||||
The Apollo client makes it easy to consume your GraphQL API. Install the client:
|
||||
|
||||
```shell
|
||||
npm install @apollo/client
|
||||
```
|
||||
|
||||
Modify your `app.tsx` to provide the Apollo Client:
|
||||
|
||||
```typescript {% fileName="apps/frontend/src/main.tsx" %}
|
||||
import { StrictMode } from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
import App from './app/app';
|
||||
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
|
||||
const client = new ApolloClient({
|
||||
uri: 'http://localhost:4000/graphql',
|
||||
cache: new InMemoryCache(),
|
||||
});
|
||||
|
||||
root.render(
|
||||
<StrictMode>
|
||||
<ApolloProvider client={client}>
|
||||
<App />
|
||||
</ApolloProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
```
|
||||
|
||||
## Create React library
|
||||
|
||||
Nx helps you break down your code into well-organized libraries for consumption by apps, so create a couple of React libraries to organize your work. Create a `data-access` library that handles communication with the backend and a `feature-sets` library that includes container components for displaying the Lego set data. In a real app, you might also create a `ui` library that includes reusable presentational components, but that is not part of this example. For more information on how to organize your React monorepo using Nx, read our book _Effective React Development with Nx_ by registering [here](https://go.nx.dev/react-book)
|
||||
|
||||
To create the described project, run this command:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react:lib --directory=libs/feature-sets feature-sets
|
||||
```
|
||||
|
||||
When prompted, answer the prompts as follows:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react:lib --directory=libs/feature-sets feature-sets
|
||||
|
||||
NX Generating @nx/react:library
|
||||
|
||||
✔ Which bundler would you like to use to build the library? Choose 'none' to skip build setup. · none
|
||||
✔ What unit test runner should be used? · none
|
||||
```
|
||||
|
||||
## Setup React Code Generation
|
||||
|
||||
A tool called GraphQL Codegen makes the development of your feature library faster.
|
||||
|
||||
You need to create some GraphQL queries and mutations for the frontend to consume. Create a file named `operations.graphql` in the projects:
|
||||
|
||||
```graphql {% fileName="libs/feature-sets/src/lib/operations.graphql" %}
|
||||
mutation addSet($name: String!, $year: String!, $numParts: Int!) {
|
||||
addSet(name: $name, year: $year, numParts: $numParts) {
|
||||
id
|
||||
name
|
||||
numParts
|
||||
year
|
||||
}
|
||||
}
|
||||
|
||||
query setList {
|
||||
allSets {
|
||||
id
|
||||
name
|
||||
numParts
|
||||
year
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Once again create a `codegen.ts` for the project:
|
||||
|
||||
```typescript {% fileName="libs/feature-sets/codegen.ts" %}
|
||||
import { CodegenConfig } from '@graphql-codegen/cli';
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: 'libs/models-graphql/src/lib/schema.graphql',
|
||||
documents: ['libs/feature-sets/src/**/*.graphql'],
|
||||
generates: {
|
||||
'libs/feature-sets/src/lib/__generated__/operations.ts': {
|
||||
plugins: ['add', 'typescript-operations', 'typescript-react-apollo'],
|
||||
config: {
|
||||
useIndexSignature: true,
|
||||
content: 'import * as types from "@nx-apollo/models-graphql"',
|
||||
namespacedImportName: 'types',
|
||||
},
|
||||
},
|
||||
},
|
||||
ignoreNoDocuments: true,
|
||||
};
|
||||
|
||||
export default config;
|
||||
```
|
||||
|
||||
This configuration grabs all of your GraphQL files and generates all the needed types and services to consume the API.
|
||||
|
||||
Add a new task in `project.json` to run this code generator:
|
||||
|
||||
```json {% fileName="libs/feature-sets/project.json" %}
|
||||
"targets": {
|
||||
"codegen": {
|
||||
"command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can run that task using the Nx CLI:
|
||||
|
||||
```shell
|
||||
npx nx codegen feature-sets
|
||||
```
|
||||
|
||||
You should now have a folder called `__generated__` in your `feature-sets` library with a file named `operations.ts`. It contains typing information about the GraphQL schema and the operations you defined. It even has some hooks that make consuming this API superfast.
|
||||
|
||||
## Create React components
|
||||
|
||||
You now have everything needed to start building your React components. Create two components: a list of Lego sets and a form to add a Lego set. Use Nx generators to scaffold these:
|
||||
|
||||
```shell
|
||||
npx nx generate @nx/react:component libs/feature-sets/src/lib/add-set-form
|
||||
```
|
||||
|
||||
```shell
|
||||
npx nx generate @nx/react:component libs/feature-sets/src/lib/set-list
|
||||
```
|
||||
|
||||
When prompted, answer the prompts as follows:
|
||||
|
||||
```shell
|
||||
❯ npx nx generate @nx/react:component libs/feature-sets/src/lib/add-set-form
|
||||
|
||||
NX Generating @nx/react:component
|
||||
|
||||
✔ Should this component be exported in the project? (y/N) · false
|
||||
```
|
||||
|
||||
In the `SetList` component, add the following:
|
||||
|
||||
```tsx {% fileName="libs/feature-sets/src/lib/set-list.tsx" %}
|
||||
import { useSetListQuery } from './__generated__/operations';
|
||||
|
||||
export function SetList() {
|
||||
const { loading, data } = useSetListQuery();
|
||||
|
||||
return loading ? (
|
||||
<p>Loading ...</p>
|
||||
) : (
|
||||
<ul className="mx-6 w-full list-none">
|
||||
{data &&
|
||||
data.allSets?.map(({ id, name, numParts, year }) => (
|
||||
<li className="p-2 even:bg-slate-200">
|
||||
{year} - <strong>{name}</strong> ({numParts} parts)
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
export default SetList;
|
||||
```
|
||||
|
||||
Notice how `useSetListQuery` is imported from the data-access library. This is a hook generated by GraphQL Codegen that provides the results of the `SetList` query. This entire pipeline is type-safe, using the types generated by GraphQL Codegen.
|
||||
|
||||
In the `AddSetForm` component, add the following:
|
||||
|
||||
```tsx {% fileName="libs/feature-sets/src/lib/add-set-form.tsx" %}
|
||||
import { useRef } from 'react';
|
||||
import { useAddSetMutation } from './__generated__/operations';
|
||||
|
||||
export function AddSetForm() {
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
const [addSet] = useAddSetMutation({
|
||||
refetchQueries: ['setList'],
|
||||
});
|
||||
|
||||
const handleSubmit = (formData: FormData) => {
|
||||
const name = formData.get('name')?.toString();
|
||||
const year = formData.get('year')?.toString();
|
||||
const numParts = parseInt(formData.get('numParts')?.toString() || '0', 10);
|
||||
|
||||
if (name && year && numParts > 0) {
|
||||
addSet({ variables: { name, year, numParts } });
|
||||
}
|
||||
formRef.current?.reset();
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
ref={formRef}
|
||||
action={handleSubmit}
|
||||
className="mx-6 max-w-60 border border-slate-200 p-6"
|
||||
>
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="block text-sm/6 font-medium text-gray-900"
|
||||
>
|
||||
Name
|
||||
</label>
|
||||
<div className="mt-2">
|
||||
<input
|
||||
id="name"
|
||||
name="name"
|
||||
type="text"
|
||||
className="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="mt-2 block text-sm/6 font-medium text-gray-900"
|
||||
>
|
||||
Year
|
||||
</label>
|
||||
<div className="mt-2">
|
||||
<input
|
||||
id="year"
|
||||
name="year"
|
||||
type="text"
|
||||
className="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="mt-2 block text-sm/6 font-medium text-gray-900"
|
||||
>
|
||||
Number of Parts
|
||||
</label>
|
||||
<div className="mt-2">
|
||||
<input
|
||||
id="numParts"
|
||||
name="numParts"
|
||||
type="number"
|
||||
className="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="mt-6 rounded-md bg-indigo-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
>
|
||||
Create new set
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddSetForm;
|
||||
```
|
||||
|
||||
Again, notice that the component imports hooks, queries, and typing information from our generated code to accomplish this.
|
||||
|
||||
## Integrate components into the app
|
||||
|
||||
Final step: bring those new components into `FeatureSets` component:
|
||||
|
||||
```tsx {% fileName="libs/feature-sets/src/lib/feature-sets.tsx" %}
|
||||
import AddSetForm from './add-set-form';
|
||||
import SetList from './set-list';
|
||||
|
||||
export function FeatureSets() {
|
||||
return (
|
||||
<div className="flex">
|
||||
<AddSetForm></AddSetForm>
|
||||
<SetList></SetList>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FeatureSets;
|
||||
```
|
||||
|
||||
And bring that component into your app:
|
||||
|
||||
```tsx {% fileName="apps/frontend/src/app/app.tsx" %}
|
||||
import { FeatureSets } from '@nx-apollo/feature-sets';
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="my-6 text-center text-2xl font-bold">My Lego Sets</h1>
|
||||
<FeatureSets></FeatureSets>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
If your API isn’t running already, go ahead and start it:
|
||||
|
||||
```shell
|
||||
npx nx serve api
|
||||
```
|
||||
|
||||
And now start your React app in a separate terminal:
|
||||
|
||||
```shell
|
||||
npx nx serve frontend
|
||||
```
|
||||
|
||||
Browse to [http://localhost:4200](http://localhost:4200) and see the results of your work!
|
||||
|
||||
## Extend `codegen` configuration
|
||||
|
||||
The configuration for the `codegen` targets is a good start, but it's currently lacking two things:
|
||||
|
||||
1. [Caching](/features/cache-task-results)
|
||||
2. [Dependent tasks](/concepts/task-pipeline-configuration)
|
||||
|
||||
Without caching enabled, `codegen` tasks will be run every time, regardless if they need to be or not. And without dependent tasks configured, we can't be sure that `codegen` is run any time our generated code depends on the generated code in another project. IOn our example, the generated code in both `api` and `feature-sets` rely on the models generated in `models-graphql`. If we make changes to the schema in `models-graph` and then run `codegen` on `api`, our models will be out-of-sync and lead to errors.
|
||||
|
||||
Let's fix both of these problems with a target default for `codegen`. In `nx.json`, add this:
|
||||
|
||||
```json {% fileName="nx.json" %}
|
||||
"targetDefaults": {
|
||||
...
|
||||
"codegen": {
|
||||
"cache": true,
|
||||
"outputs": ["{projectRoot}/src/__generated__"],
|
||||
"inputs": ["{workspaceRoot}/libs/models-graphql/src/lib/schema.graphql","{projectRoot}/**/*.graphql"],
|
||||
"dependsOn": ["^codegen"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now try running `codegen` for `api` to see that `codegen` for `models-graphql` is run first:
|
||||
|
||||
```shell
|
||||
❯ npx nx codegen api
|
||||
|
||||
✔ 1/1 dependent project tasks succeeded [0 read from cache]
|
||||
|
||||
Hint: you can run the command with --verbose to see the full dependent project outputs
|
||||
|
||||
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
> nx run api:codegen
|
||||
|
||||
> npx graphql-codegen --config apps/api/codegen.ts
|
||||
|
||||
✔ Parse Configuration
|
||||
✔ Generate outputs
|
||||
|
||||
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
NX Successfully ran target codegen for project api and 1 task it depends on (2s)
|
||||
|
||||
```
|
||||
|
||||
Try running the command again, and you'll see that the results are pulled from the cache, and the task ends immediately.
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Apollo Server](https://www.apollographql.com/docs/apollo-server)
|
||||
- [Apollo React Client](https://www.apollographql.com/docs/react/)
|
||||
- [GraphQL Codegen](https://the-guild.dev/graphql/codegen)
|
||||
- 🧠 [Nx Docs](/getting-started/intro)
|
||||
- 👩💻 [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
@@ -1,21 +1,19 @@
|
||||
---
|
||||
title: "React Development for 2025"
|
||||
description: "In this webinar, we’ll dive into building modern React applications using platform-native tools like NPM workspaces and TypeScript project references.
|
||||
description: "In this webinar, we’ll dive into building modern React applications using platform-native tools like NPM workspaces and TypeScript project references.
|
||||
Learn how Nx improves the developer experience all while letting you ship your React apps faster. We’ll explore features like project references, how they work, and why they can significantly improve the performance of large React and TypeScript monorepos, both locally and on CI."
|
||||
date: 2025-02-26
|
||||
slug: 'react-development-for-2025'
|
||||
authors: ['Juri Strumpflohner']
|
||||
tags: [webinar]
|
||||
cover_image: /blog/images/2025-02-26/Feb-Webinar-Card.png
|
||||
time: 2-3pm ET/7-8pm UTC
|
||||
status: Upcoming
|
||||
status: Past - Gated
|
||||
registrationUrl: https://go.nx.dev/feb2025-webinar
|
||||
---
|
||||
|
||||
**Feb 26, 2025 - 2-3pm ET/7-8pm UTC**
|
||||
|
||||
Presented by Juri Strumpflohner
|
||||
|
||||
In this webinar, we’ll dive into building modern React applications using platform-native tools like NPM workspaces and TypeScript project references.
|
||||
Learn how Nx improves the developer experience all while letting you ship your React apps faster. We’ll explore features like project references, how they work, and why they can significantly improve the performance of large React and TypeScript monorepos, both locally and on CI.
|
||||
|
||||
{% call-to-action title="Register today!" url="https://go.nx.dev/feb2025-webinar" description="Save your spot" /%}
|
||||
{% call-to-action title="Download the recording" url="https://go.nx.dev/feb2025-webinar" description="Sign up to gain access" /%}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
title: 'Making Cursor Smarter with an MCP Server For Nx Monorepos'
|
||||
slug: nx-made-cursor-smarter
|
||||
authors: ['Juri Strumpflohner', 'Max Kless']
|
||||
tags: ['nx']
|
||||
cover_image: /blog/images/articles/cursor-nx-mcp-heroimg.jpg
|
||||
description: 'Learn how Nx enhances Cursor IDE with a dedicated MCP server, providing AI assistants with rich monorepo metadata for smarter code assistance.'
|
||||
youtubeUrl: https://youtu.be/V2W94Sq_v6A
|
||||
---
|
||||
|
||||
{% callout type="deepdive" title="Series: Making your LLM smarter" expanded=true %}
|
||||
|
||||
- [Nx Just Made Your LLM Way Smarter](/blog/nx-just-made-your-llm-smarter)
|
||||
- **Making Cursor Smarter**
|
||||
|
||||
{% /callout %}
|
||||
|
||||
A couple of weeks ago, we [announced how Nx makes your LLM smarter](/blog/nx-just-made-your-llm-smarter) by providing rich metadata about your monorepo structure, project relationships, and architectural context. This enhancement was initially available through GitHub Copilot in VSCode, but now we're taking it a step further by implementing the Model Context Protocol (MCP) for Cursor, making your AI assistant even more powerful.
|
||||
|
||||
{% call-to-action title="Learn more about Nx and AI" url="https://go.nx.dev/march2025-webinar" description="LLM-focused Webinar on March 19th" /%}
|
||||
|
||||
{% toc /%}
|
||||
|
||||
## What is the Model Context Protocol (MCP)?
|
||||
|
||||
The Model Context Protocol is an open standard - pioneered by [Anthropic](https://www.anthropic.com/) - that enables AI models to interact with your development environment in a more structured and powerful way. It provides a standardized interface for tools and resources that can be used by AI assistants to better understand and interact with your codebase.
|
||||
|
||||

|
||||
|
||||
_(Source: [Official MCP documentation](https://modelcontextprotocol.io))_
|
||||
|
||||
According to the [MCP documentation](https://modelcontextprotocol.io/introduction), it's designed to:
|
||||
|
||||
- Provide structured access to development tools and resources
|
||||
- Enable AI models to take actions in your development environment
|
||||
- Create a consistent interface for different AI assistants
|
||||
- Allow for better context management and tool selection
|
||||
|
||||
This protocol is particularly powerful for monorepo development because it allows AI assistants to understand not just individual files, but the entire workspace structure, project relationships, and available tools. When combined with Nx's rich metadata about your monorepo, it creates an incredibly powerful development experience.
|
||||
|
||||
The advantage of MCP is that it can become a standard. In fact, more and more libraries provide implementations (e.g. [Spring AI's MCP integration](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html)).
|
||||
|
||||
We're leveraging this by exposing such an MCP from our Nx Language server that comes with Nx Console so Cursor and other MCP compatible clients can automatically hook into the data Nx has about your workspace.
|
||||
|
||||
## How to enable it in your Cursor IDE
|
||||
|
||||
Getting started with Nx's MCP integration in Cursor is straightforward. Here's what you need to do:
|
||||
|
||||
**Install Nx Console** in your Cursor IDE by following our [editor setup guide](/getting-started/editor-setup).
|
||||
|
||||
Once installed, Cursor will automatically detect Nx Console and prompt you to configure the MCP server. You'll see a notification like this:
|
||||
|
||||

|
||||
|
||||
**Click on the notification** to open Cursor's settings. The Nx Console notification conveniently provides a direct link to the MCP settings:
|
||||
|
||||

|
||||
|
||||
In the settings, you'll see the Nx Console MCP server listed as "Disabled". **Click on it to enable it**:
|
||||
|
||||

|
||||
|
||||
Once enabled, you'll see the server status change:
|
||||
|
||||

|
||||
|
||||
If this is your first MCP installation, you'll notice a new `.cursor/mcp.json` file in your workspace. This file contains your MCP configuration:
|
||||
|
||||

|
||||
|
||||
Share this configuration with your team to ensure consistent settings or add it to `.gitignore` if you prefer to keep your local configuration private.
|
||||
|
||||
That's it! Your Cursor IDE is now configured to use Nx's MCP integration. For more details about the available features and capabilities, check out our [AI enhancement documentation](/features/enhance-AI).
|
||||
|
||||
{% callout type="note" title="Manual Setup" %}
|
||||
If you've missed the notification, you can always run the `nx.configureMcpServer` command via the command prompt (`Ctrl/Cmd` + `Shift` + `P`) and install the MCP server that way.
|
||||
{% /callout %}
|
||||
|
||||
## How it works
|
||||
|
||||
The Nx MCP integration is built on top of the official [Model Context Protocol TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk). When you enable the integration, we automatically spin up a local MCP server that communicates with Cursor using Server-Sent Events (SSE). This server runs on a random available port on your localhost, ensuring it doesn't conflict with other services.
|
||||
|
||||

|
||||
|
||||
The MCP server is configured through the `.cursor/mcp.json` file, which is automatically created in your workspace as mentioned in the previous section. Nx Console will automatically read the port specified there and spin up a matching MCP server.
|
||||
You can always view and modify the configuration through `Cursor Settings -> MCP`.
|
||||
|
||||
### Available Tools
|
||||
|
||||
While the Model Context Protocol defines various functionalities (tools, resources, roots, and sampling), support in popular clients like Cursor or Claude Desktop is limited. For now, we've focused on providing a set of essential tools that leverage Nx's rich metadata:
|
||||
|
||||
- `nx_workspace`: Provides an annotated representation of your Nx configuration and project graph
|
||||
- `nx_project_details`: Returns comprehensive configuration for any specific Nx project
|
||||
- `nx_docs`: Retrieves relevant documentation sections based on your queries
|
||||
- `nx_generators`: Lists all available code generators in your workspace
|
||||
- `nx_generator_schema`: Provides detailed schema information for specific generators
|
||||
- `nx_visualize_graph`: Opens interactive project or task graph visualizations directly in your IDE
|
||||
|
||||
### Data Flow
|
||||
|
||||
Behind the scenes, we use the Nx Language Server (`nxls`) that comes as part of the [Nx Console extension](/getting-started/editor-setup) to gather workspace information. Each tool request triggers a specific data flow:
|
||||
|
||||
1. The tool receives your query
|
||||
2. `nxls` retrieves relevant workspace information from your Nx workspace
|
||||
3. We transform this data into a format optimized for LLM consumption
|
||||
4. The transformed data is enriched with natural language descriptions
|
||||
5. The result is passed back to the AI assistant
|
||||
|
||||
For example, when handling project graph queries, we transform the raw graph data into a more structured format that includes explanations about project relationships and dependencies. You can see this transformation in action in our [project graph transformation code](https://github.com/nrwl/nx-console/blob/9a0425d8c0ae74d326bdd030e8793f2c4d0161e9/libs/shared/llm-context/src/lib/project-graph.ts#L5).
|
||||
|
||||
### IDE Integration
|
||||
|
||||
The MCP's true potential lies in its deep integration with your IDE. Right now, it can trigger these actions directly in your IDE:
|
||||
|
||||
- Visualize the project graph focused on a specific project
|
||||
- Visualize the task graph for a specific project and target
|
||||
|
||||
This is just the beginning. We plan to expand these capabilities in future releases and would love to hear your feedback and ideas on what you'd like to see.
|
||||
|
||||
### Using MCP Outside Cursor
|
||||
|
||||
If you want to use our MCP integration with other tools that support the protocol (like Claude Desktop, Cline, Windsurf and more), you can run it in `stdio` mode. This allows direct communication between the client and server process. Follow the instructions in the [nx-mcp npm package documentation](https://www.npmjs.com/package/nx-mcp?activeTab=readme) to set this up.
|
||||
|
||||
## Let's see it in action
|
||||
|
||||
Here are some example queries, showing how Cursor leverages the different exposed Nx MCP tools to get more information to correctly take action. Jump to the [Youtube video for the full run-through]().
|
||||
|
||||
**Query:** "If I change the public API of feat-product-detail, which other projects might be affected by that change?"
|
||||
|
||||
{% video-player src="/documentation/blog/media/nx-mcp-cursor-dependencies.mp4" alt="Asking Cursor about the impact of changing a project's public API" showDescription=true showControls=true autoPlay=false loop=false /%}
|
||||
|
||||
**Query:** "Use Nx to generate a new React library for handling past orders."
|
||||
|
||||
{% video-player src="/documentation/blog/media/nx-mcp-cursor-generate-project.mp4" alt="Asking Cursor to generate a new React project for listing past orders" showDescription=true showControls=true autoPlay=false loop=false /%}
|
||||
|
||||
**Query:** "Can you configure Nx release for the packages of this workspace? Just update nx.json with the necessary configuration. Use conventional commits as the versioning strategy. Also feel free to use the Nx docs to pull more info on how to configure it."
|
||||
|
||||
{% video-player src="/documentation/blog/media/nx-mcp-cursor-nx-release.mp4" alt="Asking Cursor to use the docs to configure Nx release for the workspace" showDescription=true showControls=true autoPlay=false loop=false /%}
|
||||
|
||||
## Wrapping up
|
||||
|
||||
This is just our very first version of developing an MCP server. The protocol is evolving as we speak and getting more powerful by implementing new possibilities for enriching your LLM queries with more contextual data.
|
||||
|
||||
But already these first interactions show how much more helpful and precise the answers become, making Cursor specifically a lot more useful.
|
||||
|
||||
We **want your feedback though!** Reach out on our socials ([Twitter/X](https://x.com/NxDevTools), [Bluesky](https://bsky.app/profile/nx.dev) and [LinkedIn](https://www.linkedin.com/company/nrwl/)) or hop into our [weekly office hours on Discord](http://go.nx.dev/office-hours).
|
||||
|
||||
Stay tuned for more updates on this MCP integration as well as enhancements on the [VSCode Copilot front](/blog/nx-just-made-your-llm-smarter).
|
||||
|
||||
---
|
||||
|
||||
Learn more:
|
||||
|
||||
- 🧠 [Nx AI Docs](/features/enhance-AI)
|
||||
- 👩💻 [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: 'Are Monorepos the Answer to Better AI-Assisted Development?'
|
||||
description: 'In this webinar, Nx CTO Victor Savkin and Senior Engineer Max Kless will break down **why monorepos are inherently more AI-friendly**, giving LLMs the full context they need to generate more accurate, actionable insights. You’ll also learn how Nx provides deep architectural awareness, making AI tools smarter and more effective.'
|
||||
date: 2025-03-06
|
||||
slug: 'are-monorepos-the-answer-to-better-aiassisted-development'
|
||||
authors: ['Victor Savkin', 'Max Kless']
|
||||
tags: [webinar]
|
||||
cover_image: /blog/images/2025-03-19/March-2025-Webinar-card.png
|
||||
time: 1pm EDT/5pm UTC
|
||||
status: Upcoming
|
||||
registrationUrl: https://go.nx.dev/march2025-webinar
|
||||
---
|
||||
|
||||
**Mar 19, 2025 - 1pm EDT/5pm UTC**
|
||||
|
||||
Presented by Victor Savkin and Max Kless
|
||||
|
||||
In this webinar, Nx CTO Victor Savkin and Senior Engineer Max Kless will break down **why monorepos are inherently more AI-friendly**, giving LLMs the full context they need to generate more accurate, actionable insights. You’ll also learn how Nx provides deep architectural awareness, making AI tools smarter and more effective.
|
||||
|
||||
{% call-to-action title="Register today!" url="https://go.nx.dev/march2025-webinar" description="Save your spot" /%}
|
||||
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 582 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -47,12 +47,6 @@ Show the graph where every node is either an ancestor or a descendant of todos-f
|
||||
nx graph --focus=todos-feature-main
|
||||
```
|
||||
|
||||
Include project-one and project-two in the project graph:
|
||||
|
||||
```shell
|
||||
nx graph --include=project-one,project-two
|
||||
```
|
||||
|
||||
Exclude project-one and project-two from the project graph:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -17,10 +17,11 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Type | Description |
|
||||
| ------------------------ | ------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `--help` | boolean | Show help. |
|
||||
| `--interactive` | boolean | When false disables interactive input prompts for options. (Default: `true`) |
|
||||
| `--nxCloud` | boolean | Set up distributed caching with Nx Cloud. |
|
||||
| `--useDotNxInstallation` | boolean | Initialize an Nx workspace setup in the .nx directory of the current repository. (Default: `false`) |
|
||||
| `--version` | boolean | Show version number. |
|
||||
| Option | Type | Description |
|
||||
| ------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--force` | boolean | Force the migration to continue and ignore custom webpack setup or uncommitted changes. Only for CRA projects. (Default: `false`) |
|
||||
| `--help` | boolean | Show help. |
|
||||
| `--interactive` | boolean | When false disables interactive input prompts for options. (Default: `true`) |
|
||||
| `--nxCloud` | boolean | Set up distributed caching with Nx Cloud. |
|
||||
| `--useDotNxInstallation` | boolean | Initialize an Nx workspace setup in the .nx directory of the current repository. (Default: `false`) |
|
||||
| `--version` | boolean | Show version number. |
|
||||
|
||||
@@ -14,8 +14,8 @@ while allowing tracking of the full tree of different nested versions
|
||||
### Properties
|
||||
|
||||
- [data](../../devkit/documents/ProjectGraphExternalNode#data): Object
|
||||
- [name](../../devkit/documents/ProjectGraphExternalNode#name): `npm:${string}`
|
||||
- [type](../../devkit/documents/ProjectGraphExternalNode#type): "npm"
|
||||
- [name](../../devkit/documents/ProjectGraphExternalNode#name): string
|
||||
- [type](../../devkit/documents/ProjectGraphExternalNode#type): string
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -35,10 +35,10 @@ while allowing tracking of the full tree of different nested versions
|
||||
|
||||
### name
|
||||
|
||||
• **name**: \`npm:$\{string}\`
|
||||
• **name**: `string`
|
||||
|
||||
---
|
||||
|
||||
### type
|
||||
|
||||
• **type**: `"npm"`
|
||||
• **type**: `string`
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
# Function: isDaemonEnabled
|
||||
|
||||
▸ **isDaemonEnabled**(`nxJson?`): `boolean`
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------- | :----------------------------------------------------------------------------------------- |
|
||||
| `nxJson` | [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)\<`string`[] \| `"*"`\> |
|
||||
▸ **isDaemonEnabled**(): `boolean`
|
||||
|
||||
#### Returns
|
||||
|
||||
|
||||
@@ -674,6 +674,84 @@
|
||||
"path": "/ci/recipes/source-control-integration",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "dte",
|
||||
"name": "Manual Distributed Task Execution",
|
||||
"description": "Manual DTE on your own CI provider",
|
||||
"mediaImage": "",
|
||||
"file": "",
|
||||
"itemList": [
|
||||
{
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/jenkins-dte",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "enterprise",
|
||||
"name": "Enterprise",
|
||||
@@ -770,84 +848,6 @@
|
||||
"path": "/ci/recipes/enterprise/single-tenant",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "dte",
|
||||
"name": "Custom Distributed Task Execution",
|
||||
"description": "Custom DTE on your own CI provider",
|
||||
"mediaImage": "",
|
||||
"file": "",
|
||||
"itemList": [
|
||||
{
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "conformance",
|
||||
"name": "Conformance",
|
||||
@@ -1281,6 +1281,150 @@
|
||||
"path": "/ci/recipes/source-control-integration/azure-devops",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte": {
|
||||
"id": "dte",
|
||||
"name": "Manual Distributed Task Execution",
|
||||
"description": "Manual DTE on your own CI provider",
|
||||
"mediaImage": "",
|
||||
"file": "",
|
||||
"itemList": [
|
||||
{
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/jenkins-dte",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte/github-dte": {
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte/circle-ci-dte": {
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte/azure-dte": {
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte/bitbucket-dte": {
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte/gitlab-dte": {
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/dte/jenkins-dte": {
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Manual DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/dte/jenkins-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise": {
|
||||
"id": "enterprise",
|
||||
"name": "Enterprise",
|
||||
@@ -1377,84 +1521,6 @@
|
||||
"path": "/ci/recipes/enterprise/single-tenant",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "dte",
|
||||
"name": "Custom Distributed Task Execution",
|
||||
"description": "Custom DTE on your own CI provider",
|
||||
"mediaImage": "",
|
||||
"file": "",
|
||||
"itemList": [
|
||||
{
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "conformance",
|
||||
"name": "Conformance",
|
||||
@@ -1660,150 +1726,6 @@
|
||||
"path": "/ci/recipes/enterprise/single-tenant/custom-github-app",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte": {
|
||||
"id": "dte",
|
||||
"name": "Custom Distributed Task Execution",
|
||||
"description": "Custom DTE on your own CI provider",
|
||||
"mediaImage": "",
|
||||
"file": "",
|
||||
"itemList": [
|
||||
{
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte/github-dte": {
|
||||
"id": "github-dte",
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/github-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte/circle-ci-dte": {
|
||||
"id": "circle-ci-dte",
|
||||
"name": "Circle CI Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/circle-ci-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte/azure-dte": {
|
||||
"id": "azure-dte",
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/azure-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte/bitbucket-dte": {
|
||||
"id": "bitbucket-dte",
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/bitbucket-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte/gitlab-dte": {
|
||||
"id": "gitlab-dte",
|
||||
"name": "GitLab Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/gitlab-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/dte/jenkins-dte": {
|
||||
"id": "jenkins-dte",
|
||||
"name": "Jenkins Custom DTE",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "nx-cloud/enterprise/dte/jenkins-dte",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"tags": []
|
||||
},
|
||||
"/ci/recipes/enterprise/conformance": {
|
||||
"id": "conformance",
|
||||
"name": "Conformance",
|
||||
|
||||
@@ -47,21 +47,13 @@
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "TypeScript Packages",
|
||||
"name": "TypeScript Monorepo",
|
||||
"path": "/getting-started/tutorials/typescript-packages-tutorial",
|
||||
"id": "typescript-packages-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "React Standalone",
|
||||
"path": "/getting-started/tutorials/react-standalone-tutorial",
|
||||
"id": "react-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "React Monorepo",
|
||||
"path": "/getting-started/tutorials/react-monorepo-tutorial",
|
||||
@@ -70,14 +62,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Angular Standalone",
|
||||
"path": "/getting-started/tutorials/angular-standalone-tutorial",
|
||||
"id": "angular-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Angular Monorepo",
|
||||
"path": "/getting-started/tutorials/angular-monorepo-tutorial",
|
||||
@@ -86,14 +70,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Vue Standalone",
|
||||
"path": "/getting-started/tutorials/vue-standalone-tutorial",
|
||||
"id": "vue-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Gradle Monorepo",
|
||||
"path": "/getting-started/tutorials/gradle-tutorial",
|
||||
@@ -147,21 +123,13 @@
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "TypeScript Packages",
|
||||
"name": "TypeScript Monorepo",
|
||||
"path": "/getting-started/tutorials/typescript-packages-tutorial",
|
||||
"id": "typescript-packages-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "React Standalone",
|
||||
"path": "/getting-started/tutorials/react-standalone-tutorial",
|
||||
"id": "react-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "React Monorepo",
|
||||
"path": "/getting-started/tutorials/react-monorepo-tutorial",
|
||||
@@ -170,14 +138,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Angular Standalone",
|
||||
"path": "/getting-started/tutorials/angular-standalone-tutorial",
|
||||
"id": "angular-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Angular Monorepo",
|
||||
"path": "/getting-started/tutorials/angular-monorepo-tutorial",
|
||||
@@ -186,14 +146,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Vue Standalone",
|
||||
"path": "/getting-started/tutorials/vue-standalone-tutorial",
|
||||
"id": "vue-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Gradle Monorepo",
|
||||
"path": "/getting-started/tutorials/gradle-tutorial",
|
||||
@@ -206,21 +158,13 @@
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "TypeScript Packages",
|
||||
"name": "TypeScript Monorepo",
|
||||
"path": "/getting-started/tutorials/typescript-packages-tutorial",
|
||||
"id": "typescript-packages-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "React Standalone",
|
||||
"path": "/getting-started/tutorials/react-standalone-tutorial",
|
||||
"id": "react-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "React Monorepo",
|
||||
"path": "/getting-started/tutorials/react-monorepo-tutorial",
|
||||
@@ -229,14 +173,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Angular Standalone",
|
||||
"path": "/getting-started/tutorials/angular-standalone-tutorial",
|
||||
"id": "angular-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Angular Monorepo",
|
||||
"path": "/getting-started/tutorials/angular-monorepo-tutorial",
|
||||
@@ -245,14 +181,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Vue Standalone",
|
||||
"path": "/getting-started/tutorials/vue-standalone-tutorial",
|
||||
"id": "vue-standalone-tutorial",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Gradle Monorepo",
|
||||
"path": "/getting-started/tutorials/gradle-tutorial",
|
||||
@@ -307,6 +235,14 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Automate Updating Dependencies",
|
||||
"path": "/features/automate-updating-dependencies",
|
||||
@@ -431,6 +367,14 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Automate Updating Dependencies",
|
||||
"path": "/features/automate-updating-dependencies",
|
||||
@@ -4268,9 +4212,9 @@
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Large Repo and DTE",
|
||||
"path": "/showcase/benchmarks/dte",
|
||||
"id": "dte",
|
||||
"name": "Large Repo and Nx Agents",
|
||||
"path": "/showcase/benchmarks/nx-agents",
|
||||
"id": "nx-agents",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
@@ -4569,9 +4513,9 @@
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Large Repo and DTE",
|
||||
"path": "/showcase/benchmarks/dte",
|
||||
"id": "dte",
|
||||
"name": "Large Repo and Nx Agents",
|
||||
"path": "/showcase/benchmarks/nx-agents",
|
||||
"id": "nx-agents",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
@@ -4596,9 +4540,9 @@
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Large Repo and DTE",
|
||||
"path": "/showcase/benchmarks/dte",
|
||||
"id": "dte",
|
||||
"name": "Large Repo and Nx Agents",
|
||||
"path": "/showcase/benchmarks/nx-agents",
|
||||
"id": "nx-agents",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
@@ -6034,6 +5978,63 @@
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Manual Distributed Task Execution",
|
||||
"path": "/ci/recipes/dte",
|
||||
"id": "dte",
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "GitHub Actions Manual DTE",
|
||||
"path": "/ci/recipes/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Manual DTE",
|
||||
"path": "/ci/recipes/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Manual DTE",
|
||||
"path": "/ci/recipes/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Manual DTE",
|
||||
"path": "/ci/recipes/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Manual DTE",
|
||||
"path": "/ci/recipes/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Manual DTE",
|
||||
"path": "/ci/recipes/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
}
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Enterprise",
|
||||
"path": "/ci/recipes/enterprise",
|
||||
@@ -6105,63 +6106,6 @@
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Custom Distributed Task Execution",
|
||||
"path": "/ci/recipes/enterprise/dte",
|
||||
"id": "dte",
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
}
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Conformance",
|
||||
"path": "/ci/recipes/enterprise/conformance",
|
||||
@@ -6477,6 +6421,111 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Manual Distributed Task Execution",
|
||||
"path": "/ci/recipes/dte",
|
||||
"id": "dte",
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "GitHub Actions Manual DTE",
|
||||
"path": "/ci/recipes/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Manual DTE",
|
||||
"path": "/ci/recipes/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Manual DTE",
|
||||
"path": "/ci/recipes/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Manual DTE",
|
||||
"path": "/ci/recipes/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Manual DTE",
|
||||
"path": "/ci/recipes/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Manual DTE",
|
||||
"path": "/ci/recipes/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
}
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitHub Actions Manual DTE",
|
||||
"path": "/ci/recipes/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Manual DTE",
|
||||
"path": "/ci/recipes/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Manual DTE",
|
||||
"path": "/ci/recipes/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Manual DTE",
|
||||
"path": "/ci/recipes/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Manual DTE",
|
||||
"path": "/ci/recipes/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Manual DTE",
|
||||
"path": "/ci/recipes/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Enterprise",
|
||||
"path": "/ci/recipes/enterprise",
|
||||
@@ -6548,63 +6597,6 @@
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Custom Distributed Task Execution",
|
||||
"path": "/ci/recipes/enterprise/dte",
|
||||
"id": "dte",
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
}
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Conformance",
|
||||
"path": "/ci/recipes/enterprise/conformance",
|
||||
@@ -6754,111 +6746,6 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Custom Distributed Task Execution",
|
||||
"path": "/ci/recipes/enterprise/dte",
|
||||
"id": "dte",
|
||||
"isExternal": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
}
|
||||
],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitHub Actions Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/github-dte",
|
||||
"id": "github-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Circle CI Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/circle-ci-dte",
|
||||
"id": "circle-ci-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Azure Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/azure-dte",
|
||||
"id": "azure-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Bitbucket Pipelines Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/bitbucket-dte",
|
||||
"id": "bitbucket-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "GitLab Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/gitlab-dte",
|
||||
"id": "gitlab-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Jenkins Custom DTE",
|
||||
"path": "/ci/recipes/enterprise/dte/jenkins-dte",
|
||||
"id": "jenkins-dte",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Conformance",
|
||||
"path": "/ci/recipes/enterprise/conformance",
|
||||
|
||||
@@ -435,6 +435,36 @@
|
||||
}
|
||||
},
|
||||
"migrations": {
|
||||
"/nx-api/angular/migrations/20.5.0-angular-eslint-package-updates": {
|
||||
"description": "",
|
||||
"file": "generated/packages/angular/migrations/20.5.0-angular-eslint-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-angular-eslint-package-updates",
|
||||
"version": "20.5.0-rc.1",
|
||||
"originalFilePath": "/packages/angular",
|
||||
"path": "/nx-api/angular/migrations/20.5.0-angular-eslint-package-updates",
|
||||
"type": "migration"
|
||||
},
|
||||
"/nx-api/angular/migrations/update-angular-cli-version-19-2-0": {
|
||||
"description": "Update the @angular/cli package version to ~19.2.0.",
|
||||
"file": "generated/packages/angular/migrations/update-angular-cli-version-19-2-0.json",
|
||||
"hidden": false,
|
||||
"name": "update-angular-cli-version-19-2-0",
|
||||
"version": "20.5.0-beta.5",
|
||||
"originalFilePath": "/packages/angular",
|
||||
"path": "/nx-api/angular/migrations/update-angular-cli-version-19-2-0",
|
||||
"type": "migration"
|
||||
},
|
||||
"/nx-api/angular/migrations/20.5.0-package-updates": {
|
||||
"description": "",
|
||||
"file": "generated/packages/angular/migrations/20.5.0-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.5",
|
||||
"originalFilePath": "/packages/angular",
|
||||
"path": "/nx-api/angular/migrations/20.5.0-package-updates",
|
||||
"type": "migration"
|
||||
},
|
||||
"/nx-api/angular/migrations/update-angular-cli-version-19-1-0": {
|
||||
"description": "Update the @angular/cli package version to ~19.1.0.",
|
||||
"file": "generated/packages/angular/migrations/update-angular-cli-version-19-1-0.json",
|
||||
@@ -2719,6 +2749,16 @@
|
||||
"executors": {},
|
||||
"generators": {},
|
||||
"migrations": {
|
||||
"/nx-api/module-federation/migrations/20.5.0": {
|
||||
"description": "",
|
||||
"file": "generated/packages/module-federation/migrations/20.5.0.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0",
|
||||
"version": "20.5.0-beta.5",
|
||||
"originalFilePath": "/packages/module-federation",
|
||||
"path": "/nx-api/module-federation/migrations/20.5.0",
|
||||
"type": "migration"
|
||||
},
|
||||
"/nx-api/module-federation/migrations/20.4.0-package-updates": {
|
||||
"description": "",
|
||||
"file": "generated/packages/module-federation/migrations/20.4.0-package-updates.json",
|
||||
@@ -5154,7 +5194,7 @@
|
||||
"file": "generated/packages/rspack/migrations/20.5.0-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.3",
|
||||
"version": "20.5.0-beta.4",
|
||||
"originalFilePath": "/packages/rspack",
|
||||
"path": "/nx-api/rspack/migrations/20.5.0-package-updates",
|
||||
"type": "migration"
|
||||
@@ -5955,6 +5995,16 @@
|
||||
}
|
||||
},
|
||||
"migrations": {
|
||||
"/nx-api/webpack/migrations/20.5.0-package-updates": {
|
||||
"description": "",
|
||||
"file": "generated/packages/webpack/migrations/20.5.0-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.3",
|
||||
"originalFilePath": "/packages/webpack",
|
||||
"path": "/nx-api/webpack/migrations/20.5.0-package-updates",
|
||||
"type": "migration"
|
||||
},
|
||||
"/nx-api/webpack/migrations/19.7.0-package-updates": {
|
||||
"description": "",
|
||||
"file": "generated/packages/webpack/migrations/19.7.0-package-updates.json",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"itemList": [
|
||||
{
|
||||
"id": "typescript-packages-tutorial",
|
||||
"name": "TypeScript Packages",
|
||||
"name": "TypeScript Monorepo",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/typescript-packages",
|
||||
@@ -68,17 +68,6 @@
|
||||
"path": "/getting-started/tutorials/typescript-packages-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "react-standalone-tutorial",
|
||||
"name": "React Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/react-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/react-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "react-monorepo-tutorial",
|
||||
"name": "React Monorepo",
|
||||
@@ -90,17 +79,6 @@
|
||||
"path": "/getting-started/tutorials/react-monorepo-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "angular-standalone-tutorial",
|
||||
"name": "Angular Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/angular-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/angular-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "angular-monorepo-tutorial",
|
||||
"name": "Angular Monorepo",
|
||||
@@ -112,17 +90,6 @@
|
||||
"path": "/getting-started/tutorials/angular-monorepo-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "vue-standalone-tutorial",
|
||||
"name": "Vue Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/vue-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/vue-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gradle-tutorial",
|
||||
"name": "Gradle Monorepo",
|
||||
@@ -197,7 +164,7 @@
|
||||
"itemList": [
|
||||
{
|
||||
"id": "typescript-packages-tutorial",
|
||||
"name": "TypeScript Packages",
|
||||
"name": "TypeScript Monorepo",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/typescript-packages",
|
||||
@@ -206,17 +173,6 @@
|
||||
"path": "/getting-started/tutorials/typescript-packages-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "react-standalone-tutorial",
|
||||
"name": "React Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/react-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/react-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "react-monorepo-tutorial",
|
||||
"name": "React Monorepo",
|
||||
@@ -228,17 +184,6 @@
|
||||
"path": "/getting-started/tutorials/react-monorepo-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "angular-standalone-tutorial",
|
||||
"name": "Angular Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/angular-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/angular-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "angular-monorepo-tutorial",
|
||||
"name": "Angular Monorepo",
|
||||
@@ -250,17 +195,6 @@
|
||||
"path": "/getting-started/tutorials/angular-monorepo-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "vue-standalone-tutorial",
|
||||
"name": "Vue Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/vue-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/vue-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "gradle-tutorial",
|
||||
"name": "Gradle Monorepo",
|
||||
@@ -279,7 +213,7 @@
|
||||
},
|
||||
"/getting-started/tutorials/typescript-packages-tutorial": {
|
||||
"id": "typescript-packages-tutorial",
|
||||
"name": "TypeScript Packages",
|
||||
"name": "TypeScript Monorepo",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/typescript-packages",
|
||||
@@ -288,17 +222,6 @@
|
||||
"path": "/getting-started/tutorials/typescript-packages-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
"/getting-started/tutorials/react-standalone-tutorial": {
|
||||
"id": "react-standalone-tutorial",
|
||||
"name": "React Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/react-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/react-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
"/getting-started/tutorials/react-monorepo-tutorial": {
|
||||
"id": "react-monorepo-tutorial",
|
||||
"name": "React Monorepo",
|
||||
@@ -310,17 +233,6 @@
|
||||
"path": "/getting-started/tutorials/react-monorepo-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
"/getting-started/tutorials/angular-standalone-tutorial": {
|
||||
"id": "angular-standalone-tutorial",
|
||||
"name": "Angular Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/angular-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/angular-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
"/getting-started/tutorials/angular-monorepo-tutorial": {
|
||||
"id": "angular-monorepo-tutorial",
|
||||
"name": "Angular Monorepo",
|
||||
@@ -332,17 +244,6 @@
|
||||
"path": "/getting-started/tutorials/angular-monorepo-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
"/getting-started/tutorials/vue-standalone-tutorial": {
|
||||
"id": "vue-standalone-tutorial",
|
||||
"name": "Vue Standalone",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/tutorials/vue-standalone",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/getting-started/tutorials/vue-standalone-tutorial",
|
||||
"tags": []
|
||||
},
|
||||
"/getting-started/tutorials/gradle-tutorial": {
|
||||
"id": "gradle-tutorial",
|
||||
"name": "Gradle Monorepo",
|
||||
@@ -416,6 +317,17 @@
|
||||
"path": "/features/generate-code",
|
||||
"tags": ["generate-code"]
|
||||
},
|
||||
{
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"tags": ["inferred-tasks", "project-linking", "sync"]
|
||||
},
|
||||
{
|
||||
"id": "automate-updating-dependencies",
|
||||
"name": "Automate Updating Dependencies",
|
||||
@@ -587,6 +499,17 @@
|
||||
"path": "/features/generate-code",
|
||||
"tags": ["generate-code"]
|
||||
},
|
||||
"/features/maintain-ts-monorepos": {
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"tags": ["inferred-tasks", "project-linking", "sync"]
|
||||
},
|
||||
"/features/automate-updating-dependencies": {
|
||||
"id": "automate-updating-dependencies",
|
||||
"name": "Automate Updating Dependencies",
|
||||
@@ -5847,14 +5770,14 @@
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "dte",
|
||||
"name": "Large Repo and DTE",
|
||||
"id": "nx-agents",
|
||||
"name": "Large Repo and Nx Agents",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/examples/dte",
|
||||
"file": "shared/examples/nx-agents",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/showcase/benchmarks/dte",
|
||||
"path": "/showcase/benchmarks/nx-agents",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
@@ -6261,14 +6184,14 @@
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "dte",
|
||||
"name": "Large Repo and DTE",
|
||||
"id": "nx-agents",
|
||||
"name": "Large Repo and Nx Agents",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/examples/dte",
|
||||
"file": "shared/examples/nx-agents",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/showcase/benchmarks/dte",
|
||||
"path": "/showcase/benchmarks/nx-agents",
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
@@ -6298,15 +6221,15 @@
|
||||
"path": "/showcase/benchmarks/caching",
|
||||
"tags": []
|
||||
},
|
||||
"/showcase/benchmarks/dte": {
|
||||
"id": "dte",
|
||||
"name": "Large Repo and DTE",
|
||||
"/showcase/benchmarks/nx-agents": {
|
||||
"id": "nx-agents",
|
||||
"name": "Large Repo and Nx Agents",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/examples/dte",
|
||||
"file": "shared/examples/nx-agents",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/showcase/benchmarks/dte",
|
||||
"path": "/showcase/benchmarks/nx-agents",
|
||||
"tags": []
|
||||
},
|
||||
"/reference": {
|
||||
|
||||
@@ -382,6 +382,110 @@
|
||||
"path": "/nx-api/nx/documents/generate"
|
||||
}
|
||||
],
|
||||
"inferred-tasks": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/mental-model",
|
||||
"id": "mental-model",
|
||||
"name": "Mental Model",
|
||||
"path": "/concepts/mental-model"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/nx-plugins",
|
||||
"id": "nx-plugins",
|
||||
"name": "What Are Nx Plugins",
|
||||
"path": "/concepts/nx-plugins"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/inferred-tasks",
|
||||
"id": "inferred-tasks",
|
||||
"name": "Inferred Tasks",
|
||||
"path": "/concepts/inferred-tasks"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/running-tasks/convert-to-inferred",
|
||||
"id": "convert-to-inferred",
|
||||
"name": "Migrate to Inferred Tasks (Project Crystal)",
|
||||
"path": "/recipes/running-tasks/convert-to-inferred"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/plugins/project-graph-plugins",
|
||||
"id": "project-graph-plugins",
|
||||
"name": "Infer Tasks or Projects",
|
||||
"path": "/extending-nx/recipes/project-graph-plugins"
|
||||
}
|
||||
],
|
||||
"project-linking": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/typescript-project-linking",
|
||||
"id": "typescript-project-linking",
|
||||
"name": "TypeScript Project Linking",
|
||||
"path": "/concepts/typescript-project-linking"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/tips-n-tricks/switch-to-workspaces-project-references",
|
||||
"id": "switch-to-workspaces-project-references",
|
||||
"name": "Switch to Workspaces and TS Project References",
|
||||
"path": "/recipes/tips-n-tricks/switch-to-workspaces-project-references"
|
||||
}
|
||||
],
|
||||
"sync": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/sync-generators",
|
||||
"id": "sync-generators",
|
||||
"name": "Sync Generators",
|
||||
"path": "/concepts/sync-generators"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/generators/create-sync-generator",
|
||||
"id": "create-sync-generator",
|
||||
"name": "Create a Sync Generator",
|
||||
"path": "/extending-nx/recipes/create-sync-generator"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync",
|
||||
"id": "sync",
|
||||
"name": "sync",
|
||||
"path": "/nx-api/nx/documents/sync"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync-check",
|
||||
"id": "sync-check",
|
||||
"name": "sync:check",
|
||||
"path": "/nx-api/nx/documents/sync-check"
|
||||
}
|
||||
],
|
||||
"automate-updating-dependencies": [
|
||||
{
|
||||
"description": "Learn how Nx provides automated update scripts to help you keep your workspace, tooling and framework dependencies up to date.",
|
||||
@@ -621,43 +725,6 @@
|
||||
"path": "/concepts/mental-model"
|
||||
}
|
||||
],
|
||||
"inferred-tasks": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/mental-model",
|
||||
"id": "mental-model",
|
||||
"name": "Mental Model",
|
||||
"path": "/concepts/mental-model"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/nx-plugins",
|
||||
"id": "nx-plugins",
|
||||
"name": "What Are Nx Plugins",
|
||||
"path": "/concepts/nx-plugins"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/inferred-tasks",
|
||||
"id": "inferred-tasks",
|
||||
"name": "Inferred Tasks",
|
||||
"path": "/concepts/inferred-tasks"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/running-tasks/convert-to-inferred",
|
||||
"id": "convert-to-inferred",
|
||||
"name": "Migrate to Inferred Tasks (Project Crystal)",
|
||||
"path": "/recipes/running-tasks/convert-to-inferred"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/plugins/project-graph-plugins",
|
||||
"id": "project-graph-plugins",
|
||||
"name": "Infer Tasks or Projects",
|
||||
"path": "/extending-nx/recipes/project-graph-plugins"
|
||||
}
|
||||
],
|
||||
"add": [
|
||||
{
|
||||
"description": "",
|
||||
@@ -748,52 +815,6 @@
|
||||
"path": "/nx-api/nx/documents/daemon"
|
||||
}
|
||||
],
|
||||
"sync": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/sync-generators",
|
||||
"id": "sync-generators",
|
||||
"name": "Sync Generators",
|
||||
"path": "/concepts/sync-generators"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/generators/create-sync-generator",
|
||||
"id": "create-sync-generator",
|
||||
"name": "Create a Sync Generator",
|
||||
"path": "/extending-nx/recipes/create-sync-generator"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync",
|
||||
"id": "sync",
|
||||
"name": "sync",
|
||||
"path": "/nx-api/nx/documents/sync"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync-check",
|
||||
"id": "sync-check",
|
||||
"name": "sync:check",
|
||||
"path": "/nx-api/nx/documents/sync-check"
|
||||
}
|
||||
],
|
||||
"project-linking": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/typescript-project-linking",
|
||||
"id": "typescript-project-linking",
|
||||
"name": "TypeScript Project Linking",
|
||||
"path": "/concepts/typescript-project-linking"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/tips-n-tricks/switch-to-workspaces-project-references",
|
||||
"id": "switch-to-workspaces-project-references",
|
||||
"name": "Switch to Workspaces and TS Project References",
|
||||
"path": "/recipes/tips-n-tricks/switch-to-workspaces-project-references"
|
||||
}
|
||||
],
|
||||
"module-federation": [
|
||||
{
|
||||
"description": "",
|
||||
|
||||
@@ -430,6 +430,36 @@
|
||||
}
|
||||
],
|
||||
"migrations": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "generated/packages/angular/migrations/20.5.0-angular-eslint-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-angular-eslint-package-updates",
|
||||
"version": "20.5.0-rc.1",
|
||||
"originalFilePath": "/packages/angular",
|
||||
"path": "angular/migrations/20.5.0-angular-eslint-package-updates",
|
||||
"type": "migration"
|
||||
},
|
||||
{
|
||||
"description": "Update the @angular/cli package version to ~19.2.0.",
|
||||
"file": "generated/packages/angular/migrations/update-angular-cli-version-19-2-0.json",
|
||||
"hidden": false,
|
||||
"name": "update-angular-cli-version-19-2-0",
|
||||
"version": "20.5.0-beta.5",
|
||||
"originalFilePath": "/packages/angular",
|
||||
"path": "angular/migrations/update-angular-cli-version-19-2-0",
|
||||
"type": "migration"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "generated/packages/angular/migrations/20.5.0-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.5",
|
||||
"originalFilePath": "/packages/angular",
|
||||
"path": "angular/migrations/20.5.0-package-updates",
|
||||
"type": "migration"
|
||||
},
|
||||
{
|
||||
"description": "Update the @angular/cli package version to ~19.1.0.",
|
||||
"file": "generated/packages/angular/migrations/update-angular-cli-version-19-1-0.json",
|
||||
@@ -2700,6 +2730,16 @@
|
||||
"executors": [],
|
||||
"generators": [],
|
||||
"migrations": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "generated/packages/module-federation/migrations/20.5.0.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0",
|
||||
"version": "20.5.0-beta.5",
|
||||
"originalFilePath": "/packages/module-federation",
|
||||
"path": "module-federation/migrations/20.5.0",
|
||||
"type": "migration"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "generated/packages/module-federation/migrations/20.4.0-package-updates.json",
|
||||
@@ -5122,7 +5162,7 @@
|
||||
"file": "generated/packages/rspack/migrations/20.5.0-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.3",
|
||||
"version": "20.5.0-beta.4",
|
||||
"originalFilePath": "/packages/rspack",
|
||||
"path": "rspack/migrations/20.5.0-package-updates",
|
||||
"type": "migration"
|
||||
@@ -5918,6 +5958,16 @@
|
||||
}
|
||||
],
|
||||
"migrations": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "generated/packages/webpack/migrations/20.5.0-package-updates.json",
|
||||
"hidden": false,
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.3",
|
||||
"originalFilePath": "/packages/webpack",
|
||||
"path": "webpack/migrations/20.5.0-package-updates",
|
||||
"type": "migration"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "generated/packages/webpack/migrations/19.7.0-package-updates.json",
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Nx and Angular Versions
|
||||
description: A comprehensive compatibility matrix showing which Nx versions work with different Angular versions, including recommended versions and supported ranges.
|
||||
---
|
||||
|
||||
# Nx and Angular Versions
|
||||
|
||||
The latest version of Nx supports the [actively supported versions of Angular (current and LTS versions)](https://angular.dev/reference/releases#actively-supported-versions). Workspaces in any of those versions are recommended to use the latest version of Nx to benefit from all the new features and fixes.
|
||||
@@ -14,6 +19,7 @@ We provide a recommended version, and it is usually the latest minor version of
|
||||
|
||||
| Angular Version | **Nx Version _(recommended)_** | Nx Version _(range)_ |
|
||||
| --------------- | ------------------------------ | ---------------------------------------- |
|
||||
| ~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 | **latest** | >=19.6.0 <=latest |
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Nx and the Angular CLI
|
||||
description: Compare Nx and Angular CLI features, understand similarities and differences, and learn how Nx enhances Angular development with improved caching, monorepo support, and advanced tooling.
|
||||
---
|
||||
|
||||
# Nx and the Angular CLI
|
||||
|
||||
{% youtube
|
||||
@@ -35,7 +40,7 @@ Here's a quick side-by-side overview comparing the features between the Angular
|
||||
| Executors | ✅ (Builders) | ✅ |
|
||||
| Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ |
|
||||
| Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ |
|
||||
| Support for [single-project Workspaces](/getting-started/tutorials/angular-standalone-tutorial) | ✅ | ✅ |
|
||||
| Support for single-project Workspaces | ✅ | ✅ |
|
||||
| First-Class [Monorepo Support](/getting-started/tutorials/angular-monorepo-tutorial) | ❌\* | ✅ |
|
||||
| [Enforced Module Boundaries](/features/enforce-module-boundaries) | ❌ | ✅ |
|
||||
| Interactive [Project Graph](/features/explore-graph) | ❌ | ✅ |
|
||||
@@ -67,8 +72,6 @@ Nx is not just exclusively for monorepos, but can create
|
||||
- a single-project workspace (basically what the Angular CLI gives you)
|
||||
- a monorepo workspace (multiple projects in a single repo)
|
||||
|
||||
You can check out the [Angular single-project workspace tutorial](/getting-started/tutorials/angular-standalone-tutorial) to learn more about it.
|
||||
|
||||
### Generate a new project
|
||||
|
||||
You can create a new Nx single-project workspace using the following command:
|
||||
@@ -270,7 +273,7 @@ Nx goes beyond being just a CLI and comes with [Nx Console](/getting-started/edi
|
||||
Nx is really made to scale with you. You can
|
||||
|
||||
- start small with a single-project workspace
|
||||
- modularize your application into more fine-grained libraries for better maintainability as your application (and team) grows ([more about that here](/getting-started/tutorials/angular-standalone-tutorial#modularizing-your-angular-app-with-local-libraries)), including mechanisms to make sure [things stay within their boundaries](/features/enforce-module-boundaries)
|
||||
- modularize your application into more fine-grained libraries for better maintainability as your application (and team) grows, including mechanisms to make sure [things stay within their boundaries](/features/enforce-module-boundaries)
|
||||
- you can then migrate to a monorepo when you are ready and need one ([more here](/recipes/tips-n-tricks/standalone-to-monorepo))
|
||||
- or even [add Webpack Module Federation support](/recipes/angular/module-federation-with-ssr)
|
||||
|
||||
@@ -408,5 +411,4 @@ There is also a guide describing how to [consolidate multiple Angular CLI projec
|
||||
|
||||
You can learn more about Angular & Nx by following our dedicated tutorials:
|
||||
|
||||
- [Tutorial: Building Angular Apps with the Nx Standalone Projects Setup](/getting-started/tutorials/angular-standalone-tutorial)
|
||||
- [Tutorial: Building Angular Apps in an Nx Monorepo](/getting-started/tutorials/angular-monorepo-tutorial)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Nx Devkit and Angular Devkit
|
||||
description: Compare Nx Devkit and Angular Devkit for creating generators and executors, understand key differences in implementation, and learn how to convert between the two approaches.
|
||||
---
|
||||
|
||||
# Nx Devkit and Angular Devkit
|
||||
|
||||
{% callout type="note" title="Nx & Angular" %}
|
||||
|
||||
@@ -59,8 +59,8 @@ npm add -D @nx/angular
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
{% callout type="note" title="Angular Tutorials" %}
|
||||
For a full tutorial experience, follow the [Angular Standalone Tutorial](/getting-started/tutorials/angular-standalone-tutorial) or the [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
|
||||
{% callout type="note" title="Angular Tutorial" %}
|
||||
For a full tutorial experience, follow the [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
|
||||
{% /callout %}
|
||||
|
||||
## Using the Angular Plugin
|
||||
@@ -127,7 +127,6 @@ nx g @nx/angular:service apps/appName/src/lib/my-service/my-service
|
||||
|
||||
## More Documentation
|
||||
|
||||
- [Angular Standalone Tutorial](/getting-started/tutorials/angular-standalone-tutorial)
|
||||
- [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
|
||||
- [Migrating from the Angular CLI](/recipes/angular/migration/angular)
|
||||
- [Setup Module Federation with Angular and Nx](/concepts/module-federation/faster-builds-with-module-federation)
|
||||
|
||||
@@ -74,11 +74,11 @@
|
||||
},
|
||||
"publicHost": {
|
||||
"type": "string",
|
||||
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
|
||||
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. This option has no effect when using the 'application' or other esbuild-based builders."
|
||||
},
|
||||
"allowedHosts": {
|
||||
"type": "array",
|
||||
"description": "List of hosts that are allowed to access the dev server.",
|
||||
"description": "List of hosts that are allowed to access the dev server. This option has no effect when using the 'application' or other esbuild-based builders in Angular versions lower than 19.2.0.",
|
||||
"default": [],
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
@@ -88,7 +88,7 @@
|
||||
},
|
||||
"disableHostCheck": {
|
||||
"type": "boolean",
|
||||
"description": "Don't verify connected clients are part of allowed hosts.",
|
||||
"description": "Don't verify connected clients are part of allowed hosts. This option has no effect when using the 'application' or other esbuild-based builders in Angular versions lower than 19.2.0.",
|
||||
"default": false
|
||||
},
|
||||
"hmr": {
|
||||
|
||||
@@ -21,6 +21,22 @@
|
||||
"@angular-eslint/utils": {
|
||||
"version": "^18.0.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/schematics": {
|
||||
"version": "^18.0.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/test-utils": {
|
||||
"version": "^18.0.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/builder": {
|
||||
"version": "^18.0.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/bundled-angular-compiler": {
|
||||
"version": "^18.0.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
|
||||
@@ -22,6 +22,22 @@
|
||||
"@angular-eslint/utils": {
|
||||
"version": "^19.0.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/schematics": {
|
||||
"version": "^19.0.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/test-utils": {
|
||||
"version": "^19.0.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/builder": {
|
||||
"version": "^19.0.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/bundled-angular-compiler": {
|
||||
"version": "^19.0.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
|
||||
@@ -22,6 +22,22 @@
|
||||
"@angular-eslint/utils": {
|
||||
"version": "^19.0.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/schematics": {
|
||||
"version": "^19.0.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/test-utils": {
|
||||
"version": "^19.0.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/builder": {
|
||||
"version": "^19.0.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/bundled-angular-compiler": {
|
||||
"version": "^19.0.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "20.5.0-angular-eslint-package-updates",
|
||||
"version": "20.5.0-rc.1",
|
||||
"requires": {
|
||||
"eslint": "^8.57.0 || ^9.0.0",
|
||||
"@angular/core": ">= 19.0.0 < 20.0.0"
|
||||
},
|
||||
"packages": {
|
||||
"angular-eslint": { "version": "^19.2.0", "alwaysAddToPackageJson": false },
|
||||
"@angular-eslint/eslint-plugin": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/eslint-plugin-template": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/template-parser": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/utils": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/schematics": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/test-utils": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/builder": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-eslint/bundled-angular-compiler": {
|
||||
"version": "^19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"implementation": "",
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.5",
|
||||
"x-prompt": "Do you want to update the Angular version to v19.2?",
|
||||
"requires": { "@angular/core": ">=19.1.0 <19.2.0" },
|
||||
"packages": {
|
||||
"@angular-devkit/build-angular": {
|
||||
"version": "~19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-devkit/core": {
|
||||
"version": "~19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-devkit/schematics": {
|
||||
"version": "~19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular/build": { "version": "~19.2.0", "alwaysAddToPackageJson": false },
|
||||
"@angular/pwa": { "version": "~19.2.0", "alwaysAddToPackageJson": false },
|
||||
"@angular/ssr": { "version": "~19.2.0", "alwaysAddToPackageJson": false },
|
||||
"@schematics/angular": {
|
||||
"version": "~19.2.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-devkit/architect": {
|
||||
"version": "~0.1902.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular-devkit/build-webpack": {
|
||||
"version": "~0.1902.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular/core": { "version": "~19.2.0", "alwaysAddToPackageJson": true },
|
||||
"@angular/material": {
|
||||
"version": "~19.2.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@angular/cdk": { "version": "~19.2.1", "alwaysAddToPackageJson": false },
|
||||
"ng-packagr": { "version": "~19.2.0", "alwaysAddToPackageJson": false }
|
||||
},
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"implementation": "",
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration"
|
||||
}
|
||||
@@ -11,5 +11,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Add Localize Polyfill to Targets\n\nAdd the '@angular/localize/init' polyfill to the 'polyfills' option of targets using esbuild-based executors.\n\n#### Sample Code Changes\n\nAdd the `@angular/localize/init` polyfill to any of these executors:\n\n- `@angular/build:application`\n- `@angular-devkit/build-angular:application`\n- `@nx/angular:application`\n- `@angular-devkit/build-angular:browser-esbuild`\n- `@nx/angular:browser-esbuild`\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"apps/app1/project.json\" %}\n{\n \"targets\": {\n \"build\": {\n \"executor\": \"@angular/build:application\",\n \"options\": {\n \"localize\": true\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"apps/app1/project.json\" %}\n{\n \"targets\": {\n \"build\": {\n \"executor\": \"@angular/build:application\",\n \"options\": {\n \"localize\": true,\n \"polyfills\": [\"@angular/localize/init\"]\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Ensure the @nx/module-federation Package is Installed\n\nIf workspace includes Module Federation projects, ensure the new `@nx/module-federation` package is installed.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"dependencies\": {}\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@nx/module-federation\": \"20.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Remove Angular ESLint Rules\n\nRemove Angular ESLint rules that were removed in v19.0.0.\n\n#### Sample Code Changes\n\nRemoves `@angular-eslint/no-host-metadata-property`, `@angular-eslint/sort-ngmodule-metadata-arrays` and `@angular-eslint/prefer-standalone-component` from any ESLint config file. Files to be searched include `.eslintrc.json`, `.eslintrc.base.json`, `.eslint.config.js` and `.eslint.config.base.js`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"apps/app1/.eslintrc.json\" %}\n{\n \"overrides\": [\n {\n \"files\": [\"*.ts\"],\n \"rules\": {\n \"@angular-eslint/no-host-metadata-property\": [\"error\"],\n \"@angular-eslint/sort-ngmodule-metadata-arrays\": [\"error\"],\n \"@angular-eslint/prefer-standalone-component\": [\"error\"]\n }\n }\n ]\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"apps/app1/.eslintrc.json\" %}\n{\n \"overrides\": [\n {\n \"files\": [\"*.ts\"],\n \"rules\": {}\n }\n ]\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Remove tailwindConfig from ng-packagr Executors\n\nRemove the deprecated 'tailwindConfig' option from ng-packagr executors. Tailwind CSS configurations located at the project or workspace root will be picked up automatically.\n\n#### Sample Code Changes\n\nRemove `tailwindConfig` from the `@nx/angular:ng-packagr-lite` or `@nx/angular:package` executor options in project configuration.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"libs/my-lib/project.json\" %}\n{\n \"targets\": {\n \"build\": {\n \"executor\": \"@nx/angular:ng-packagr-lite\",\n \"options\": {\n \"project\": \"libs/lib1/ng-package.json\",\n \"tailwindConfig\": \"libs/lib1/tailwind.config.js\"\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"libs/my-lib/project.json\" %}\n{\n \"targets\": {\n \"build\": {\n \"executor\": \"@nx/angular:ng-packagr-lite\",\n \"options\": {\n \"project\": \"libs/lib1/ng-package.json\"\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n\nRemove `tailwindConfig` from the `@nx/angular:ng-packagr-lite` or `@nx/angular:package` executor target defaults in `nx.json`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {\n \"@nx/angular:ng-packagr-lite\": {\n \"options\": {\n \"project\": \"{projectRoot}/ng-package.json\",\n \"tailwindConfig\": \"{projectRoot}/tailwind.config.js\"\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {\n \"@nx/angular:ng-packagr-lite\": {\n \"options\": {\n \"project\": \"{projectRoot}/ng-package.json\"\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Migrate Module Federation Imports to New Package\n\nUpdate the ModuleFederationConfig imports to use @nx/module-federation.\n\n#### Sample Code Changes\n\nUpdate import paths for ModuleFederationConfig.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```js {% fileName=\"apps/shell/webpack.config.js\" %}\nimport { ModuleFederationConfig } from '@nx/webpack';\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```js {% fileName=\"apps/shell/webpack.config.js\" %}\nimport { ModuleFederationConfig } from '@nx/module-federation';\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Migrate withModuleFederation Import to New Package\n\nUpdate the withModuleFederation import to use @nx/module-federation/webpack.\n\n#### Sample Code Changes\n\nUpdate import paths for `withModuleFederation` and `withModuleFederationForSSR`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"apps/shell/webpack.config.ts\" %}\nimport {\n withModuleFederation,\n withModuleFederationForSSR,\n} from '@nx/angular/module-federation';\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"apps/shell/webpack.config.ts\" %}\nimport {\n withModuleFederation,\n withModuleFederationForSSR,\n} from '@nx/module-federation/angular';\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Update `@angular/cli` to `~19.0.0`\n\nUpdate the version of the Angular CLI if it is specified in `package.json`\n\n#### Sample Code Changes\n\nUpdate in `devDependencies`:\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"@angular/cli\": \"~13.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"@angular/cli\": \"~19.0.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n\nUpdate in `dependencies`:\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@angular/cli\": \"~13.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@angular/cli\": \"~19.0.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Update `@angular/cli` to `~19.1.0`\n\nUpdate the version of the Angular CLI if it is specified in `package.json`\n\n#### Sample Code Changes\n\nUpdate in `devDependencies`:\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"@angular/cli\": \"~13.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"@angular/cli\": \"~19.1.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n\nUpdate in `dependencies`:\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@angular/cli\": \"~13.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```{% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@angular/cli\": \"~19.1.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "update-angular-cli-version-19-2-0",
|
||||
"cli": "nx",
|
||||
"version": "20.5.0-beta.5",
|
||||
"requires": { "@angular/core": ">=19.2.0" },
|
||||
"description": "Update the @angular/cli package version to ~19.2.0.",
|
||||
"factory": "./src/migrations/update-20-5-0/update-angular-cli",
|
||||
"implementation": "/packages/angular/src/migrations/update-20-5-0/update-angular-cli.ts",
|
||||
"aliases": [],
|
||||
"hidden": false,
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": "#### Sample Code Changes\n\nUpdate the `@angular/cli` package version in the `package.json` file at the workspace root to **~19.2.0**.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"@angular/cli\": \"~19.1.0\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[3] fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"@angular/cli\": \"~19.2.0\"\n }\n}\n```\n\n{% /tab %}\n\n{% /tabs %}\n"
|
||||
}
|
||||
@@ -11,5 +11,5 @@
|
||||
"path": "/packages/angular",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Update Angular SSR Imports to Use Node Entry Point\n\nUpdate '@angular/ssr' import paths to use the new '/node' entry point when 'CommonEngine' is detected.\n\n#### Sample Code Changes\n\nUpdate import paths for SSR CommonEngine properties to use `@angular/ssr/node`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"apps/app1/server.ts\" %}\nimport { CommonEngine } from '@angular/ssr';\nimport type {\n CommonEngineOptions,\n CommonEngineRenderOptions,\n} from '@angular/ssr';\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"apps/app1/server.ts\" %}\nimport { CommonEngine } from '@angular/ssr/node';\nimport type {\n CommonEngineOptions,\n CommonEngineRenderOptions,\n} from '@angular/ssr/node';\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Detox Plugin for Nx
|
||||
description: Learn how to set up and use Detox for end-to-end testing of mobile applications in your Nx workspace, including environment setup and configuration options.
|
||||
---
|
||||
|
||||
Detox is gray box end-to-end testing and automation library for mobile apps. It has a lot of great features:
|
||||
|
||||
- Cross Platform
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Dependency Checks ESLint Rule
|
||||
description: Learn how to use the @nx/dependency-checks ESLint rule to identify mismatches between dependencies in package.json and actual project dependencies.
|
||||
---
|
||||
|
||||
# Dependency Checks rule
|
||||
|
||||
The `@nx/dependency-checks` ESLint rule enables you to discover mismatches between dependencies specified in a project's `package.json` and the dependencies that your project depends on. If your project is using, for example, the `axios`, but the `package.json` does not specify it as a dependency, your library might not work correctly. This rule helps catch these problems before your users do.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Enforce Module Boundaries ESLint Rule
|
||||
description: Learn how to use the @nx/enforce-module-boundaries ESLint rule to define strict rules for accessing resources between different projects in your Nx workspace.
|
||||
---
|
||||
|
||||
# Enforce module boundaries rule
|
||||
|
||||
The `@nx/enforce-module-boundaries` ESLint rule enables you to define strict rules for accessing resources between
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Nx ESLint Plugin
|
||||
description: An overview of the @nx/eslint-plugin package, which provides recommended ESLint configurations and Nx-specific rules for enforcing module boundaries and dependency checks.
|
||||
---
|
||||
|
||||
The `@nx/eslint-plugin` package is an ESLint plugin that contains a collection of recommended ESLint rule configurations which you can extend from in your own ESLint configs, as well as the following Nx-specific ESLint rules:
|
||||
|
||||
- [enforce-module-boundaries](#enforce-module-boundaries-rule)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: ESLint Plugin for Nx
|
||||
description: Learn how to set up and use the @nx/eslint plugin to integrate ESLint with Nx, enabling caching and providing code generators for ESLint configuration.
|
||||
---
|
||||
|
||||
The ESLint plugin integrates [ESLint](https://eslint.org/) with Nx. It allows you to run ESLint through Nx with caching enabled. It also includes code generators to help you set up ESLint in your workspace.
|
||||
|
||||
## Setting Up @nx/eslint
|
||||
@@ -25,11 +30,13 @@ The `@nx/eslint` plugin will create a task for any project that has an ESLint co
|
||||
|
||||
- `.eslintrc`
|
||||
- `.eslintrc.js`
|
||||
- `.eslintrc.mjs`
|
||||
- `.eslintrc.cjs`
|
||||
- `.eslintrc.yaml`
|
||||
- `.eslintrc.yml`
|
||||
- `.eslintrc.json`
|
||||
- `eslint.config.js`
|
||||
- `eslint.config.mjs`
|
||||
- `eslint.config.cjs`
|
||||
|
||||
Because ESLint applies configuration files to all subdirectories, the `@nx/eslint` plugin will also infer tasks for projects in subdirectories. So, if there is an ESLint configuration file in the root of the repository, every project will have an inferred ESLint task.
|
||||
|
||||
@@ -4,7 +4,19 @@
|
||||
"packages": {
|
||||
"@typescript-eslint/parser": { "version": "^7.16.0" },
|
||||
"@typescript-eslint/eslint-plugin": { "version": "^7.16.0" },
|
||||
"@typescript-eslint/utils": { "version": "^7.16.0" }
|
||||
"@typescript-eslint/utils": { "version": "^7.16.0" },
|
||||
"@typescript-eslint/rule-tester": {
|
||||
"version": "^7.16.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "^7.16.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "^7.16.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
|
||||
@@ -4,9 +4,21 @@
|
||||
"requires": { "@typescript-eslint/eslint-plugin": ">8.0.0 <8.19.0" },
|
||||
"packages": {
|
||||
"typescript-eslint": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/parser": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/eslint-plugin": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/utils": { "version": "^8.19.0" }
|
||||
"@typescript-eslint/parser": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/utils": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/rule-tester": {
|
||||
"version": "^8.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "^8.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "^8.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
|
||||
@@ -4,9 +4,21 @@
|
||||
"requires": { "typescript-eslint": ">8.0.0 <8.19.0" },
|
||||
"packages": {
|
||||
"typescript-eslint": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/parser": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/eslint-plugin": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/utils": { "version": "^8.19.0" }
|
||||
"@typescript-eslint/parser": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/utils": { "version": "^8.19.0" },
|
||||
"@typescript-eslint/rule-tester": {
|
||||
"version": "^8.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "^8.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "^8.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"path": "/packages/eslint",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Update ESLint Config File Extensions in Overrides\n\nUpdate ESLint flat config to include .cjs, .mjs, .cts, and .mts files in overrides (if needed)\n\n#### Sample Code Changes\n\nAdd `.cjs`, `.mjs`, `.cts`, `.mts` file extensions to overrides converted using `convert-to-flat-config`\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```js {% fileName=\"eslint.config.js\" %}\nconst { FlatCompat } = require('@eslint/eslintrc');\nconst js = require('@eslint/js');\nconst nxEslintPlugin = require('@nx/eslint-plugin');\n\nconst compat = new FlatCompat({\n baseDirectory: __dirname,\n recommendedConfig: js.configs.recommended,\n});\n\nmodule.exports = [\n ...compat\n .config({\n extends: ['plugin:@nx/typescript'],\n })\n .map((config) => ({\n ...config,\n files: ['**/*.ts', '**/*.tsx'],\n rules: {\n ...config.rules,\n },\n })),\n ...compat\n .config({\n extends: ['plugin:@nx/javascript'],\n })\n .map((config) => ({\n ...config,\n files: ['**/*.js', '**/*.jsx'],\n rules: {\n ...config.rules,\n },\n })),\n];\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```js {% highlightLines=[17,28] fileName=\"eslint.config.js\" %}\nconst { FlatCompat } = require('@eslint/eslintrc');\nconst js = require('@eslint/js');\nconst nxEslintPlugin = require('@nx/eslint-plugin');\n\nconst compat = new FlatCompat({\n baseDirectory: __dirname,\n recommendedConfig: js.configs.recommended,\n});\n\nmodule.exports = [\n ...compat\n .config({\n extends: ['plugin:@nx/typescript'],\n })\n .map((config) => ({\n ...config,\n files: ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts'],\n rules: {\n ...config.rules,\n },\n })),\n ...compat\n .config({\n extends: ['plugin:@nx/javascript'],\n })\n .map((config) => ({\n ...config,\n files: ['**/*.js', '**/*.jsx', '**/*.cjs', '**/*.mjs'],\n rules: {\n ...config.rules,\n },\n })),\n];\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"path": "/packages/eslint",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Update TypeScript ESLint to v8.13.0\n\nUpdate TypeScript ESLint packages to v8.13.0 if they are already on v8\n\n#### Sample Code Changes\n\nThis migration will update `typescript-eslint`, `@typescript-eslint/eslint-plugin`, `@typescript-eslint/parser` and `@typescript-eslint/utils` to `8.13.0` if they are between version `8.0.0` and `8.13.0`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"typescript-eslint\": \"^8.0.0\",\n \"@typescript-eslint/eslint-plugin\": \"^8.0.0\",\n \"@typescript-eslint/parser\": \"^8.0.0\",\n \"@typescript-eslint/utils\": \"^8.0.0\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"devDependencies\": {\n \"typescript-eslint\": \"^8.13.0\",\n \"@typescript-eslint/eslint-plugin\": \"^8.13.0\",\n \"@typescript-eslint/parser\": \"^8.13.0\",\n \"@typescript-eslint/utils\": \"^8.13.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Expo Plugin for Nx
|
||||
description: Learn how to use the @nx/expo plugin to manage Expo applications and libraries within an Nx workspace, including setup, configuration, and task inference.
|
||||
---
|
||||
|
||||
Expo is an open-source framework for apps that run natively on Android, iOS, and the web. Expo brings together the best of mobile and the web and enables many important features for building and scaling an app.
|
||||
|
||||
Expo is a set of tools built on top of React Native. The Nx Plugin for Expo contains generators for managing Expo applications and libraries within an Nx workspace.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Express Plugin for Nx
|
||||
description: Learn how to use the @nx/express plugin to create and manage Express applications in your Nx workspace, including setup and common recipes.
|
||||
---
|
||||
|
||||
[Express](https://expressjs.com/) is a mature, minimal, and an open source web framework for making web applications and
|
||||
apis.
|
||||
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/gradle",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Add includeSubprojectsTasks to build.gradle File\n\nAdd includeSubprojectsTasks to build.gradle file\n\n#### Sample Code Changes\n\nUpdate import paths for `withModuleFederation` and `withModuleFederationForSSR`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"plugins\": [\"@nx/gradle\"]\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[5] fileName=\"nx.json\" %}\n{\n \"plugins\": [\n {\n \"options\": {\n \"includeSubprojectsTasks\": true\n },\n \"plugin\": \"@nx/gradle\"\n }\n ]\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"path": "/packages/jest",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Replace getJestProjects with getJestProjectsAsync\n\nReplace getJestProjects with getJestProjectsAsync\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjects } from '@nx/jest';\n\nexport default {\n projects: getJestProjects(),\n};\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjectsAsync } from '@nx/jest';\n\nexport default async () => ({\n projects: await getJestProjectsAsync(),\n});\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -63,6 +63,104 @@ Nx 20 updates the TS monorepo setup when using `--preset=ts`. The workspace is s
|
||||
To create with the older setup for TS monorepo with `compilerOptions.paths`, use `create-nx-workspace --preset=apps`.
|
||||
{% /callout %}
|
||||
|
||||
### How @nx/js Infers Tasks
|
||||
|
||||
The `@nx/js/typescript` plugin will add a `typecheck` task to projects that have a `tsconfig.json`.
|
||||
|
||||
This plugin adds a `build` task for projects that:
|
||||
|
||||
1. Have a runtime tsconfig file (defaults to `tsconfig.lib.json`).
|
||||
2. Have a `package.json` file containing entry points that are not source files.
|
||||
|
||||
For example, this project is buildable and will have a `build` task.
|
||||
|
||||
```json {% fileName="packages/pkg1/package.json" %}
|
||||
{
|
||||
"name": "@acme/pkg1",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Whereas this project points to source files and will not have a `build` task.
|
||||
|
||||
```json {% fileName="packages/pkg1/package.json" %}
|
||||
{
|
||||
"name": "@acme/pkg1",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### View Inferred Tasks
|
||||
|
||||
To view inferred tasks for a project, open the [project details view](/concepts/inferred-tasks) in Nx Console or run `nx show project my-project` in the command line.
|
||||
|
||||
### @nx/js Configuration
|
||||
|
||||
The `@nx/js/typescript` plugin is configured in the `plugins` array in `nx.json`.
|
||||
|
||||
```json {% fileName="nx.json" %}
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/js/typescript",
|
||||
"options": {
|
||||
"typecheck": {
|
||||
"targetName": "typecheck"
|
||||
},
|
||||
"build": {
|
||||
"targetName": "build",
|
||||
"configName": "tsconfig.lib.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can also set `typecheck` and `build` options to `false` to not infer the corresponding tasks.
|
||||
|
||||
```json {% fileName="nx.json" %}
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/js/typescript",
|
||||
"options": {
|
||||
"build": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Disable Typechecking
|
||||
|
||||
To disable `typecheck` task for a specific project, set the `nx.addTypecheckTarget` property to `false` in `tsconfig.json`.
|
||||
|
||||
```json {% fileName="packages/pkg1/tsconfig.json" highlightLines=["10-12"] %}
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
],
|
||||
"nx": {
|
||||
"addTypecheckTarget": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Create Libraries
|
||||
|
||||
You can add a new JS/TS library with the following command:
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "20.5.0",
|
||||
"version": "20.5.0-beta.5",
|
||||
"@module-federation/enhanced": {
|
||||
"version": "^0.9.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@module-federation/runtime": {
|
||||
"version": "^0.9.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@module-federation/sdk": {
|
||||
"version": "^0.9.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@module-federation/node": {
|
||||
"version": "^2.6.26",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"implementation": "",
|
||||
"path": "/packages/module-federation",
|
||||
"schema": null,
|
||||
"type": "migration"
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Nest.js Plugin for Nx
|
||||
description: Learn how to use the @nx/nest plugin to create and manage Nest.js applications and libraries in your Nx workspace, including setup and generators.
|
||||
---
|
||||
|
||||
Nest.js is a framework designed for building scalable server-side applications. In many ways, Nest is familiar to Angular developers:
|
||||
|
||||
- It has excellent TypeScript support.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Node.js Plugin for Nx
|
||||
description: Learn how to use the @nx/node plugin to create and manage Node.js applications and libraries in your Nx workspace, including setup, building, and testing.
|
||||
---
|
||||
|
||||
The Node Plugin contains generators and executors to manage Node applications within an Nx workspace. It provides:
|
||||
|
||||
## Setting Up @nx/node
|
||||
|
||||
@@ -47,12 +47,6 @@ Show the graph where every node is either an ancestor or a descendant of todos-f
|
||||
nx graph --focus=todos-feature-main
|
||||
```
|
||||
|
||||
Include project-one and project-two in the project graph:
|
||||
|
||||
```shell
|
||||
nx graph --include=project-one,project-two
|
||||
```
|
||||
|
||||
Exclude project-one and project-two from the project graph:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -17,10 +17,11 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Type | Description |
|
||||
| ------------------------ | ------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `--help` | boolean | Show help. |
|
||||
| `--interactive` | boolean | When false disables interactive input prompts for options. (Default: `true`) |
|
||||
| `--nxCloud` | boolean | Set up distributed caching with Nx Cloud. |
|
||||
| `--useDotNxInstallation` | boolean | Initialize an Nx workspace setup in the .nx directory of the current repository. (Default: `false`) |
|
||||
| `--version` | boolean | Show version number. |
|
||||
| Option | Type | Description |
|
||||
| ------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--force` | boolean | Force the migration to continue and ignore custom webpack setup or uncommitted changes. Only for CRA projects. (Default: `false`) |
|
||||
| `--help` | boolean | Show help. |
|
||||
| `--interactive` | boolean | When false disables interactive input prompts for options. (Default: `true`) |
|
||||
| `--nxCloud` | boolean | Set up distributed caching with Nx Cloud. |
|
||||
| `--useDotNxInstallation` | boolean | Initialize an Nx workspace setup in the .nx directory of the current repository. (Default: `false`) |
|
||||
| `--version` | boolean | Show version number. |
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"path": "/packages/nx",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Move useDaemonProcess\n\nMove the `useDaemonProcess` to the root of `nx.json`\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"tasksRunnerOptions\": {\n \"default\": {\n \"options\": {\n \"useDaemonProcess\": false\n }\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"useDaemonProcess\": false\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"path": "/packages/nx",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Use Legacy Cache\n\nSet `useLegacyCache` to true for migrating workspaces\n\n#### Sample Code Changes\n\nAdd `useLegacyCache` to `nx.json` unless `enableDbCache` was set to true.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {}\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {},\n \"useLegacyCache\": true\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: Nx Plugin Development
|
||||
description: Learn about the @nx/plugin package, which provides tooling to help create and maintain Nx plugins with generators and executors.
|
||||
---
|
||||
|
||||
Nx plugins are npm packages that contain [generators](/features/generate-code) and [executors](/concepts/executors-and-configurations) to extend a Nx workspace.
|
||||
|
||||
This package contains tooling to help plugin authors create and maintain plugins.
|
||||
|
||||
@@ -59,6 +59,12 @@
|
||||
"alias": "C",
|
||||
"description": "Use class components instead of functional component.",
|
||||
"default": false
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "internal"
|
||||
}
|
||||
},
|
||||
"required": ["path"],
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
title: React Plugin for Nx
|
||||
description: Learn how to use the @nx/react plugin to create and manage React applications and libraries in your Nx workspace, including components, hooks, and more.
|
||||
---
|
||||
|
||||
The React plugin contains executors and generators for managing React applications and libraries within an Nx workspace.
|
||||
It provides:
|
||||
|
||||
@@ -12,8 +17,8 @@ It provides:
|
||||
|
||||
To create a new workspace with React, run `npx create-nx-workspace@latest --preset=react-standalone`.
|
||||
|
||||
{% callout type="note" title="React Tutorials" %}
|
||||
For a full tutorial experience, follow the [React Standalone Tutorial](/getting-started/tutorials/react-standalone-tutorial) or the [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
|
||||
{% callout type="note" title="React Tutorial" %}
|
||||
For a full tutorial experience, follow the [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
|
||||
{% /callout %}
|
||||
|
||||
### Installation
|
||||
@@ -144,7 +149,6 @@ The library in `dist` is publishable to npm or a private registry.
|
||||
|
||||
## More Documentation
|
||||
|
||||
- [React Standalone Tutorial](/getting-started/tutorials/react-standalone-tutorial)
|
||||
- [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
|
||||
- [Using Cypress](/nx-api/cypress)
|
||||
- [Using Jest](/nx-api/jest)
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/react",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Add Module Federation Env Var to Target Defaults\n\nAdd NX_MF_DEV_REMOTES to inputs for task hashing when `@nx/webpack:webpack` or `@nx/rspack:rspack` is used for Module Federation.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {\n \"@nx/webpack:webpack\": {\n \"inputs\": [\"^build\"]\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[4,5,6] fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {\n \"@nx/webpack:webpack\": {\n \"cache\": true,\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\n \"^build\",\n {\n \"env\": \"NX_MF_DEV_REMOTES\"\n }\n ]\n }\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/react",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Add Module Federation Env Var to Target Defaults\n\nAdd NX_MF_DEV_REMOTES to inputs for task hashing when `@nx/webpack:webpack` or `@nx/rspack:rspack` is used for Module Federation.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {\n \"@nx/webpack:webpack\": {\n \"inputs\": [\"^build\"]\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[4,5,6] fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {\n \"@nx/webpack:webpack\": {\n \"cache\": true,\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\n \"^build\",\n {\n \"env\": \"NX_MF_DEV_REMOTES\"\n }\n ]\n }\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/react",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Ensure the @nx/module-federation Package is Installed\n\nIf workspace includes Module Federation projects, ensure the new `@nx/module-federation` package is installed.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"dependencies\": {}\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@nx/module-federation\": \"20.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/react",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Migrate Module Federation Imports to New Package\n\nUpdate the ModuleFederationConfig imports to use @nx/module-federation.\n\n#### Sample Code Changes\n\nUpdate import paths for ModuleFederationConfig.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```js {% fileName=\"apps/shell/webpack.config.js\" %}\nimport { ModuleFederationConfig } from '@nx/webpack';\n```\n\n```js {% fileName=\"apps/shell/rspack.config.js\" %}\nimport { ModuleFederationConfig } from '@nx/rspack/module-federation';\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```js {% fileName=\"apps/shell/webpack.config.js\" %}\nimport { ModuleFederationConfig } from '@nx/module-federation';\n```\n\n```js {% fileName=\"apps/shell/rspack.config.js\" %}\nimport { ModuleFederationConfig } from '@nx/module-federation';\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/react",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Migrate withModuleFederation Import to New Package\n\nUpdate the withModuleFederation import to use @nx/module-federation/webpack.\n\n#### Sample Code Changes\n\nUpdate import paths for `withModuleFederation` and `withModuleFederationForSSR`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"apps/shell/webpack.config.ts\" %}\nimport {\n withModuleFederation,\n withModuleFederationForSSR,\n} from '@nx/react/module-federation';\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"apps/shell/webpack.config.ts\" %}\nimport {\n withModuleFederation,\n withModuleFederationForSSR,\n} from '@nx/module-federation/webpack';\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -286,10 +286,24 @@
|
||||
"description": "Paths to include. Paths will be resolved to project root.",
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"sassOptions": {
|
||||
"description": "Options to pass to sass-loader.",
|
||||
"type": "object"
|
||||
},
|
||||
"lessOptions": {
|
||||
"description": "Options to pass to less-loader.",
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"sassImplementation": {
|
||||
"type": "string",
|
||||
"description": "The implementation of the SASS compiler to use. Can be either `sass` or `sass-embedded`. Defaults to `sass-embedded`.",
|
||||
"enum": ["sass", "sass-embedded"],
|
||||
"default": "sass"
|
||||
},
|
||||
"styles": {
|
||||
"type": "array",
|
||||
"description": "External Styles which will be included with the application",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "20.5.0-package-updates",
|
||||
"version": "20.5.0-beta.3",
|
||||
"version": "20.5.0-beta.4",
|
||||
"packages": {
|
||||
"sass-loader": { "version": "^16.0.4", "alwaysAddToPackageJson": false },
|
||||
"@rspack/core": { "version": "^1.2.2", "alwaysAddToPackageJson": false }
|
||||
},
|
||||
"aliases": [],
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/rspack",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Ensure the @nx/module-federation Package is Installed\n\nIf workspace includes Module Federation projects, ensure the new `@nx/module-federation` package is installed.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"dependencies\": {}\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"package.json\" %}\n{\n \"dependencies\": {\n \"@nx/module-federation\": \"20.3.0\"\n }\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"path": "/packages/rspack",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": ""
|
||||
"examplesFile": "#### Migrate withModuleFederation Import to New Package\n\nUpdate the withModuleFederation import to use @nx/module-federation/rspack.\n\n#### Sample Code Changes\n\nUpdate import paths for `withModuleFederation` and `withModuleFederationForSSR`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"apps/shell/rspack.config.ts\" %}\nimport {\n withModuleFederation,\n withModuleFederationForSSR,\n} from '@nx/rspack/module-federation';\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"apps/shell/rspack.config.ts\" %}\nimport {\n withModuleFederation,\n withModuleFederationForSSR,\n} from '@nx/module-federation/rspack';\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
|
||||
@@ -23,6 +23,178 @@
|
||||
"alwaysAddToPackageJson": true
|
||||
},
|
||||
"storybook": { "version": "^8.2.8", "alwaysAddToPackageJson": true },
|
||||
"@storybook/addon-controls": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/addon-jest": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/addon-mdx-gfm": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/addon-onboarding": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/addon-themes": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/blocks": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/builder-manager": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/builder-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/cli": { "version": "^8.2.8", "alwaysAddToPackageJson": false },
|
||||
"@storybook/components": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/core": { "version": "^8.2.8", "alwaysAddToPackageJson": false },
|
||||
"@storybook/core-common": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/core-events": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/core-webpack": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/csf-tools": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/html": { "version": "^8.2.8", "alwaysAddToPackageJson": false },
|
||||
"@storybook/html-vite": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/html-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/manager": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/manager-api": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/nextjs": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preact": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preact-vite": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preact-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-create-react-app": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-html-webpack": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-preact-webpack": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-react-webpack": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-server-webpack": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-vue3-webpack": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/react-vite": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/react-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/router": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/server": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/server-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/svelte": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/svelte-vite": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/sveltekit": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/theming": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/types": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/vue3": { "version": "^8.2.8", "alwaysAddToPackageJson": false },
|
||||
"@storybook/vue3-vite": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/vue3-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/web-components": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/web-components-vite": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/web-components-webpack5": {
|
||||
"version": "^8.2.8",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/test-runner": {
|
||||
"version": "^0.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
|
||||
@@ -102,6 +102,145 @@
|
||||
"@storybook/vue3-vite": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/addon-onboarding": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/addon-themes": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/blocks": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/builder-manager": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/builder-webpack5": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/cli": { "version": "^8.4.6", "alwaysAddToPackageJson": false },
|
||||
"@storybook/components": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/core": { "version": "^8.4.6", "alwaysAddToPackageJson": false },
|
||||
"@storybook/core-common": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/core-events": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/core-webpack": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/csf-tools": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/html": { "version": "^8.4.6", "alwaysAddToPackageJson": false },
|
||||
"@storybook/html-vite": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/html-webpack5": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/manager": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/manager-api": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/nextjs": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preact": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preact-vite": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preact-webpack5": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-create-react-app": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-html-webpack": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-preact-webpack": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-react-webpack": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-server-webpack": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/preset-vue3-webpack": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/router": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/server": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/server-webpack5": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/svelte": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/svelte-vite": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/sveltekit": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/theming": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/types": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/vue3-webpack5": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@storybook/web-components": {
|
||||
"version": "^8.4.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
},
|
||||
"aliases": [],
|
||||
|
||||