Revert "docs(core): publish tutorial kit tutorials (#30973)" (#31179)

This reverts commit 2cb0fa2b55e6a00f35928435332941b4742bf5e3.

Removes the tutorialkit tutorials.
This commit is contained in:
Isaac Mann 2025-05-12 15:23:41 -04:00 committed by GitHub
parent 07c8b4f41b
commit 07474a4092
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
157 changed files with 3855 additions and 1132 deletions

View File

@ -50,8 +50,8 @@ There will be more content around choosing which style and even how to mix the t
We also updated our docs to have two super short tutorials that illustrate the two approaches: We also updated our docs to have two super short tutorials that illustrate the two approaches:
- [/tutorials/1-ts-packages/1t-introduction/1-welcome](/tutorials/1-ts-packages/1t-introduction/1-welcome) - [/getting-started/tutorials/typescript-packages-tutorial](/getting-started/tutorials/typescript-packages-tutorial)
- [/tutorials/2-react-monorepo/1r-introduction/1-welcome](/tutorials/2-react-monorepo/1r-introduction/1-welcome) - [/getting-started/tutorials/react-monorepo-tutorial](/getting-started/tutorials/react-monorepo-tutorial)
You can also read more about the concept here: [/deprecated/integrated-vs-package-based](/deprecated/integrated-vs-package-based) You can also read more about the concept here: [/deprecated/integrated-vs-package-based](/deprecated/integrated-vs-package-based)
@ -179,9 +179,9 @@ It is an ongoing process, and we have a lot of content to cover! We follow the [
- you want to learn something new ("Tutorial" section) or - you want to learn something new ("Tutorial" section) or
- you want a solution to a specific problem ("Recipes" section). - you want a solution to a specific problem ("Recipes" section).
Besides the two new [package-based](/tutorials/1-ts-packages/1t-introduction/1-welcome) and [integrated style tutorials](/tutorials/2-react-monorepo/1r-introduction/1-welcome) we also have two brand new reworked tutorials 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
- [/tutorials](/tutorials) - [/getting-started/tutorials](/getting-started/tutorials)
Stay tuned for more updates to come. Stay tuned for more updates to come.

View File

@ -59,7 +59,7 @@ You can pass `--vite=false` if you still want to keep the Webpack configuration
## Generating a Tailwind Setup ## Generating a Tailwind Setup
Once you have a [Nx-based React](/tutorials/2-react-monorepo/1r-introduction/1-welcome) 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 ```shell
$ npx nx g @nrwl/react:setup-tailwind $ npx nx g @nrwl/react:setup-tailwind
@ -79,7 +79,7 @@ You'll get
You should be all setup and ready now! Here are some related resources to explore: You should be all setup and ready now! Here are some related resources to explore:
- [Nx docs: React Monorepo tutorial](/tutorials/2-react-monorepo/1r-introduction/1-welcome) - [Nx docs: React Monorepo tutorial](/getting-started/tutorials/react-monorepo-tutorial)
- [Youtube: Is CRA Dead](https://youtu.be/fkTz6KJxhhE) - [Youtube: Is CRA Dead](https://youtu.be/fkTz6KJxhhE)
- [Nx docs: Migrate CRA to React and Vite](/recipes/adopting-nx/adding-to-existing-project) - [Nx docs: Migrate CRA to React and Vite](/recipes/adopting-nx/adding-to-existing-project)

View File

@ -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 - We could also include "[executors](/extending-nx/recipes/local-executors)", which are wrappers around tasks to abstract the lower-level details of it
- etc. - 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: [/tutorials/2-react-monorepo/1r-introduction/1-welcome](/tutorials/2-react-monorepo/1r-introduction/1-welcome) 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 ## Learn more

View File

@ -26,7 +26,7 @@ Juri also dives deeper into efforts from the team to provide high quality educat
![](/blog/images/2023-10-13/bodyimg2.webp) ![](/blog/images/2023-10-13/bodyimg2.webp)
This makes it easier to find keep the content organized and focused and makes it easier for the reader to choose between solution-oriented [recipes](/recipes) vs learning-oriented [tutorials](/tutorials). This makes it easier to find keep the content organized and focused and makes it easier for the reader to choose between solution-oriented [recipes](/recipes) vs learning-oriented [tutorials](/getting-started/tutorials).
The Nx team not only produces written content, but also video content mainly on the [Nx YouTube Channel](https://www.youtube.com/@nxdevtools). Juri shows some of the growth stats, with the channel now having more than 14k subscribers and around 3.7k hours of watch time per month. The channel serves mostly short-form videos about new releases, highlighting new features as well as longer-form tutorial videos. The Nx team not only produces written content, but also video content mainly on the [Nx YouTube Channel](https://www.youtube.com/@nxdevtools). Juri shows some of the growth stats, with the channel now having more than 14k subscribers and around 3.7k hours of watch time per month. The channel serves mostly short-form videos about new releases, highlighting new features as well as longer-form tutorial videos.

View File

@ -315,7 +315,7 @@ We also poured a lot of [effort into the docs](/getting-started/intro). We restr
- [**Concept docs**](/concepts) — which explain some of the inner workings and mental model behind certain features. Like [how caching works](/concepts/how-caching-works). - [**Concept docs**](/concepts) — which explain some of the inner workings and mental model behind certain features. Like [how caching works](/concepts/how-caching-works).
- [**Recipes**](/recipes) — which are solution oriented. You already know how to cook, we provide the exact recipe for it. - [**Recipes**](/recipes) — which are solution oriented. You already know how to cook, we provide the exact recipe for it.
- [**Tutorials**](/tutorials) — for when you just want to sit down and follow along, step by step to learn how to use Nx in a certain context. - [**Tutorials**](/getting-started/tutorials) — for when you just want to sit down and follow along, step by step to learn how to use Nx in a certain context.
- [**Reference**](/reference) and [**API docs**](/nx-api) — pure, raw and to the point. - [**Reference**](/reference) and [**API docs**](/nx-api) — pure, raw and to the point.
We created a brand new ["Why Nx"](/getting-started/why-nx) page explaining the overall architecture of Nx including a [brand new video](https://www.youtube.com/watch?v=-_4WMl-Fn0w) giving you a holistic overview of what Nx is capable of. We created a brand new ["Why Nx"](/getting-started/why-nx) page explaining the overall architecture of Nx including a [brand new video](https://www.youtube.com/watch?v=-_4WMl-Fn0w) giving you a holistic overview of what Nx is capable of.

View File

@ -52,7 +52,7 @@ Emily, the engineer that worked on this effort, posted an entire article where y
Thanks to the benefits of Project Crystal - which allows us to determine information to create Nx Tasks based on the way your Gradle projects are setup - by adding this plugin, it makes it easy to add Gradle into an existing workspace without needing any Nx-specific configuration. Thanks to the benefits of Project Crystal - which allows us to determine information to create Nx Tasks based on the way your Gradle projects are setup - by adding this plugin, it makes it easy to add Gradle into an existing workspace without needing any Nx-specific configuration.
In addition, you can now find [a new tutorial on using Nx with Gradle](/tutorials/4-gradle/1g-introduction/1-welcome) which will expand on the [Spring framework](https://spring.io/)'s tutorial for multi-module projects and show you how Nx further enhances the developer experience of that workspace. This tutorial takes you all the way through setting up your CI pipeline with Nx Cloud, so be sure to check it out! In addition, you can now find [a new tutorial on using Nx with Gradle](/getting-started/tutorials/gradle-tutorial) which will expand on the [Spring framework](https://spring.io/)'s tutorial for multi-module projects and show you how Nx further enhances the developer experience of that workspace. This tutorial takes you all the way through setting up your CI pipeline with Nx Cloud, so be sure to check it out!
As an editorial note, this Gradle plugin is a big step for Nx, as it represents the first major step we're taking outside of the Javascript ecosystem. This has always been the goal: to robustly support monorepos and full-stack development, even across language and ecosystem barriers. We're using this Gradle plugin internally for our closed-sourced projects (in particular Nx Cloud) and in [Nx Console](https://github.com/nrwl/nx-console/blob/master/package.json#L74) and we're very proud of this plugin and all that it represents. As an editorial note, this Gradle plugin is a big step for Nx, as it represents the first major step we're taking outside of the Javascript ecosystem. This has always been the goal: to robustly support monorepos and full-stack development, even across language and ecosystem barriers. We're using this Gradle plugin internally for our closed-sourced projects (in particular Nx Cloud) and in [Nx Console](https://github.com/nrwl/nx-console/blob/master/package.json#L74) and we're very proud of this plugin and all that it represents.

View File

@ -103,7 +103,7 @@ Gradle projects were traditionally tricky to manage alongside JavaScript librari
**Composite Build Support** takes this further by pulling in dependencies from composite builds and reflecting them in the task graph. This release reflects our larger goal of breaking down barriers between ecosystems. Nx aims to enable efficient workflows across different languages and technologies, moving closer to a seamless polyglot monorepo experience. **Composite Build Support** takes this further by pulling in dependencies from composite builds and reflecting them in the task graph. This release reflects our larger goal of breaking down barriers between ecosystems. Nx aims to enable efficient workflows across different languages and technologies, moving closer to a seamless polyglot monorepo experience.
For more details, check out the blog post ["Manage Your Gradle Project using Nx"](/blog/manage-your-gradle-project-using-nx) and our [Gradle tutorial](/tutorials/4-gradle/1g-introduction/1-welcome). For more details, check out the blog post ["Manage Your Gradle Project using Nx"](/blog/manage-your-gradle-project-using-nx) and our [Gradle tutorial](/getting-started/tutorials/gradle-tutorial).
### Nx Import ### Nx Import

View File

@ -42,39 +42,39 @@
}, },
{ {
"name": "Tutorials", "name": "Tutorials",
"path": "/tutorials", "path": "/getting-started/tutorials",
"id": "tutorials", "id": "tutorials",
"isExternal": false, "isExternal": false,
"children": [ "children": [
{ {
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome", "path": "/getting-started/tutorials/typescript-packages-tutorial",
"id": "typescript-packages-tutorial", "id": "typescript-packages-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "React Monorepo", "name": "React Monorepo",
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome", "path": "/getting-started/tutorials/react-monorepo-tutorial",
"id": "react-monorepo-tutorial", "id": "react-monorepo-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Angular Monorepo", "name": "Angular Monorepo",
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome", "path": "/getting-started/tutorials/angular-monorepo-tutorial",
"id": "angular-monorepo-tutorial", "id": "angular-monorepo-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"path": "/tutorials/4-gradle/1g-introduction/1-welcome", "path": "/getting-started/tutorials/gradle-tutorial",
"id": "gradle-tutorial", "id": "gradle-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
} }
@ -118,39 +118,39 @@
}, },
{ {
"name": "Tutorials", "name": "Tutorials",
"path": "/tutorials", "path": "/getting-started/tutorials",
"id": "tutorials", "id": "tutorials",
"isExternal": false, "isExternal": false,
"children": [ "children": [
{ {
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome", "path": "/getting-started/tutorials/typescript-packages-tutorial",
"id": "typescript-packages-tutorial", "id": "typescript-packages-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "React Monorepo", "name": "React Monorepo",
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome", "path": "/getting-started/tutorials/react-monorepo-tutorial",
"id": "react-monorepo-tutorial", "id": "react-monorepo-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Angular Monorepo", "name": "Angular Monorepo",
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome", "path": "/getting-started/tutorials/angular-monorepo-tutorial",
"id": "angular-monorepo-tutorial", "id": "angular-monorepo-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"path": "/tutorials/4-gradle/1g-introduction/1-welcome", "path": "/getting-started/tutorials/gradle-tutorial",
"id": "gradle-tutorial", "id": "gradle-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
} }
@ -159,33 +159,33 @@
}, },
{ {
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome", "path": "/getting-started/tutorials/typescript-packages-tutorial",
"id": "typescript-packages-tutorial", "id": "typescript-packages-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "React Monorepo", "name": "React Monorepo",
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome", "path": "/getting-started/tutorials/react-monorepo-tutorial",
"id": "react-monorepo-tutorial", "id": "react-monorepo-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Angular Monorepo", "name": "Angular Monorepo",
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome", "path": "/getting-started/tutorials/angular-monorepo-tutorial",
"id": "angular-monorepo-tutorial", "id": "angular-monorepo-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"path": "/tutorials/4-gradle/1g-introduction/1-welcome", "path": "/getting-started/tutorials/gradle-tutorial",
"id": "gradle-tutorial", "id": "gradle-tutorial",
"isExternal": true, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },

View File

@ -62,10 +62,10 @@
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/typescript-packages",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome", "path": "/getting-started/tutorials/typescript-packages-tutorial",
"tags": [] "tags": []
}, },
{ {
@ -73,10 +73,10 @@
"name": "React Monorepo", "name": "React Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/react-monorepo",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome", "path": "/getting-started/tutorials/react-monorepo-tutorial",
"tags": [] "tags": []
}, },
{ {
@ -84,10 +84,10 @@
"name": "Angular Monorepo", "name": "Angular Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/angular-monorepo",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome", "path": "/getting-started/tutorials/angular-monorepo-tutorial",
"tags": [] "tags": []
}, },
{ {
@ -95,15 +95,15 @@
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/gradle",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/4-gradle/1g-introduction/1-welcome", "path": "/getting-started/tutorials/gradle-tutorial",
"tags": [] "tags": []
} }
], ],
"isExternal": false, "isExternal": false,
"path": "/tutorials", "path": "/getting-started/tutorials",
"tags": [] "tags": []
} }
], ],
@ -155,7 +155,7 @@
"path": "/getting-started/editor-setup", "path": "/getting-started/editor-setup",
"tags": ["editor-setup"] "tags": ["editor-setup"]
}, },
"/tutorials": { "/getting-started/tutorials": {
"id": "tutorials", "id": "tutorials",
"name": "Tutorials", "name": "Tutorials",
"description": "Get started with basic information, concepts and tutorials.", "description": "Get started with basic information, concepts and tutorials.",
@ -167,10 +167,10 @@
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/typescript-packages",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome", "path": "/getting-started/tutorials/typescript-packages-tutorial",
"tags": [] "tags": []
}, },
{ {
@ -178,10 +178,10 @@
"name": "React Monorepo", "name": "React Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/react-monorepo",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome", "path": "/getting-started/tutorials/react-monorepo-tutorial",
"tags": [] "tags": []
}, },
{ {
@ -189,10 +189,10 @@
"name": "Angular Monorepo", "name": "Angular Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/angular-monorepo",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome", "path": "/getting-started/tutorials/angular-monorepo-tutorial",
"tags": [] "tags": []
}, },
{ {
@ -200,59 +200,59 @@
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/gradle",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/4-gradle/1g-introduction/1-welcome", "path": "/getting-started/tutorials/gradle-tutorial",
"tags": [] "tags": []
} }
], ],
"isExternal": false, "isExternal": false,
"path": "/tutorials", "path": "/getting-started/tutorials",
"tags": [] "tags": []
}, },
"/tutorials/1-ts-packages/1t-introduction/1-welcome": { "/getting-started/tutorials/typescript-packages-tutorial": {
"id": "typescript-packages-tutorial", "id": "typescript-packages-tutorial",
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/typescript-packages",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome", "path": "/getting-started/tutorials/typescript-packages-tutorial",
"tags": [] "tags": []
}, },
"/tutorials/2-react-monorepo/1r-introduction/1-welcome": { "/getting-started/tutorials/react-monorepo-tutorial": {
"id": "react-monorepo-tutorial", "id": "react-monorepo-tutorial",
"name": "React Monorepo", "name": "React Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/react-monorepo",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome", "path": "/getting-started/tutorials/react-monorepo-tutorial",
"tags": [] "tags": []
}, },
"/tutorials/3-angular-monorepo/1a-introduction/1-welcome": { "/getting-started/tutorials/angular-monorepo-tutorial": {
"id": "angular-monorepo-tutorial", "id": "angular-monorepo-tutorial",
"name": "Angular Monorepo", "name": "Angular Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/angular-monorepo",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome", "path": "/getting-started/tutorials/angular-monorepo-tutorial",
"tags": [] "tags": []
}, },
"/tutorials/4-gradle/1g-introduction/1-welcome": { "/getting-started/tutorials/gradle-tutorial": {
"id": "gradle-tutorial", "id": "gradle-tutorial",
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"description": "", "description": "",
"mediaImage": "", "mediaImage": "",
"file": "", "file": "shared/tutorials/gradle",
"itemList": [], "itemList": [],
"isExternal": true, "isExternal": false,
"path": "/tutorials/4-gradle/1g-introduction/1-welcome", "path": "/getting-started/tutorials/gradle-tutorial",
"tags": [] "tags": []
}, },
"/features": { "/features": {

View File

@ -41,7 +41,7 @@ Here's a quick side-by-side overview comparing the features between the Angular
| Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ | | Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ |
| Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ | | Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ |
| Support for single-project Workspaces | ✅ | ✅ | | Support for single-project Workspaces | ✅ | ✅ |
| First-Class [Monorepo Support](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) | ❌\* | ✅ | | First-Class [Monorepo Support](/getting-started/tutorials/angular-monorepo-tutorial) | ❌\* | ✅ |
| [Enforced Module Boundaries](/features/enforce-module-boundaries) | ❌ | ✅ | | [Enforced Module Boundaries](/features/enforce-module-boundaries) | ❌ | ✅ |
| Interactive [Project Graph](/features/explore-graph) | ❌ | ✅ | | Interactive [Project Graph](/features/explore-graph) | ❌ | ✅ |
| Task Graph | ❌ | ✅ | | Task Graph | ❌ | ✅ |
@ -411,4 +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: You can learn more about Angular & Nx by following our dedicated tutorials:
- [Tutorial: Building Angular Apps in an Nx Monorepo](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) - [Tutorial: Building Angular Apps in an Nx Monorepo](/getting-started/tutorials/angular-monorepo-tutorial)

View File

@ -46,7 +46,7 @@ nx add @nx/angular
This will install the correct version of `@nx/angular`. This will install the correct version of `@nx/angular`.
{% callout type="note" title="Angular Tutorial" %} {% callout type="note" title="Angular Tutorial" %}
For a full tutorial experience, follow the [Angular Monorepo Tutorial](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) For a full tutorial experience, follow the [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
{% /callout %} {% /callout %}
## Using the Angular Plugin ## Using the Angular Plugin
@ -113,7 +113,7 @@ nx g @nx/angular:service apps/appName/src/lib/my-service/my-service
## More Documentation ## More Documentation
- [Angular Monorepo Tutorial](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) - [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
- [Migrating from the Angular CLI](/recipes/angular/migration/angular) - [Migrating from the Angular CLI](/recipes/angular/migration/angular)
- [Setup Module Federation with Angular and Nx](/concepts/module-federation/faster-builds-with-module-federation) - [Setup Module Federation with Angular and Nx](/concepts/module-federation/faster-builds-with-module-federation)
- [Using Tailwind CSS with Angular projects](/recipes/angular/using-tailwind-css-with-angular-projects) - [Using Tailwind CSS with Angular projects](/recipes/angular/using-tailwind-css-with-angular-projects)

View File

@ -19,7 +19,7 @@ It provides:
To create a new workspace with React, run `npx create-nx-workspace@latest --preset=react-standalone`. To create a new workspace with React, run `npx create-nx-workspace@latest --preset=react-standalone`.
{% callout type="note" title="React Tutorial" %} {% callout type="note" title="React Tutorial" %}
For a full tutorial experience, follow the [React Monorepo Tutorial](/tutorials/2-react-monorepo/1r-introduction/1-welcome) For a full tutorial experience, follow the [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
{% /callout %} {% /callout %}
### Installation ### Installation
@ -135,7 +135,7 @@ The library in `dist` is publishable to npm or a private registry.
## More Documentation ## More Documentation
- [React Monorepo Tutorial](/tutorials/2-react-monorepo/1r-introduction/1-welcome) - [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
- [Using Cypress](/nx-api/cypress) - [Using Cypress](/nx-api/cypress)
- [Using Jest](/nx-api/jest) - [Using Jest](/nx-api/jest)
- [Using Storybook](/recipes/storybook/overview-react) - [Using Storybook](/recipes/storybook/overview-react)

View File

@ -39,35 +39,26 @@
"name": "Tutorials", "name": "Tutorials",
"id": "tutorials", "id": "tutorials",
"description": "Get started with basic information, concepts and tutorials.", "description": "Get started with basic information, concepts and tutorials.",
"path": "/tutorials",
"itemList": [ "itemList": [
{ {
"name": "TypeScript Monorepo", "name": "TypeScript Monorepo",
"id": "typescript-packages-tutorial", "id": "typescript-packages-tutorial",
"file": "", "file": "shared/tutorials/typescript-packages"
"path": "/tutorials/1-ts-packages/1t-introduction/1-welcome",
"isExternal": true
}, },
{ {
"name": "React Monorepo", "name": "React Monorepo",
"id": "react-monorepo-tutorial", "id": "react-monorepo-tutorial",
"file": "", "file": "shared/tutorials/react-monorepo"
"path": "/tutorials/2-react-monorepo/1r-introduction/1-welcome",
"isExternal": true
}, },
{ {
"name": "Angular Monorepo", "name": "Angular Monorepo",
"id": "angular-monorepo-tutorial", "id": "angular-monorepo-tutorial",
"file": "", "file": "shared/tutorials/angular-monorepo"
"path": "/tutorials/3-angular-monorepo/1a-introduction/1-welcome",
"isExternal": true
}, },
{ {
"name": "Gradle Monorepo", "name": "Gradle Monorepo",
"id": "gradle-tutorial", "id": "gradle-tutorial",
"file": "", "file": "shared/tutorials/gradle"
"path": "/tutorials/4-gradle/1g-introduction/1-welcome",
"isExternal": true
} }
] ]
} }

View File

@ -36,7 +36,7 @@ Someone who appreciates the flexibility of a package-based repository will be mo
- Easily create new projects or tools with [code generators](/features/generate-code) - Easily create new projects or tools with [code generators](/features/generate-code)
{% cards %} {% cards %}
{% card title="TypeScript Monorepo Tutorial" description="Add Nx to an existing TypeScript repo" type="documentation" url="/tutorials/1-ts-packages/1t-introduction/1-welcome" /%} {% card title="TypeScript Monorepo Tutorial" description="Add Nx to an existing TypeScript repo" type="documentation" url="/getting-started/tutorials/typescript-packages-tutorial" /%}
{% /cards %} {% /cards %}
## Integrated Repos ## Integrated Repos
@ -52,8 +52,8 @@ Someone who appreciates the structure and consistency of an integrated repositor
- [Automate updating dependencies](/features/automate-updating-dependencies) of the entire toolchain - [Automate updating dependencies](/features/automate-updating-dependencies) of the entire toolchain
{% cards %} {% cards %}
{% card title="Tutorial: React Monorepo" description="Create a React monorepo with Nx" type="documentation" url="/tutorials/2-react-monorepo/1r-introduction/1-welcome" /%} {% card title="Tutorial: React Monorepo" description="Create a React monorepo with Nx" type="documentation" url="/getting-started/tutorials/react-monorepo-tutorial" /%}
{% card title="Tutorial: Angular Monorepo" description="Create an Angular monorepo with Nx" type="documentation" url="/tutorials/3-angular-monorepo/1a-introduction/1-welcome" /%} {% card title="Tutorial: Angular Monorepo" description="Create an Angular monorepo with Nx" type="documentation" url="/getting-started/tutorials/angular-monorepo-tutorial" /%}
{% /cards %} {% /cards %}
## Standalone Applications ## Standalone Applications

View File

@ -156,9 +156,9 @@ To avoid potential issues, it is [recommended to update one major version of Nx
Try one of these tutorials for a full walkthrough of what to do after you install Nx Try one of these tutorials for a full walkthrough of what to do after you install Nx
- [TypeScript Monorepo Tutorial](/tutorials/1-ts-packages/1t-introduction/1-welcome) - [TypeScript Monorepo Tutorial](/getting-started/tutorials/typescript-packages-tutorial)
- [React Monorepo Tutorial](/tutorials/2-react-monorepo/1r-introduction/1-welcome) - [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
- [Angular Monorepo Tutorial](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) - [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
## More Documentation ## More Documentation

View File

@ -66,13 +66,13 @@ Also, here are some recipes that give you more details based on the technology s
{% cards cols="2" lgCols="4" mdCols="4" smCols="2" %} {% cards cols="2" lgCols="4" mdCols="4" smCols="2" %}
{% link-card title="TypeScript Monorepo" type="tutorial" isExternal="true" url="/tutorials/1-ts-packages/1t-introduction/1-welcome" icon="jsMono" /%} {% link-card title="TypeScript Monorepo" type="tutorial" url="/getting-started/tutorials/typescript-packages-tutorial" icon="jsMono" /%}
{% link-card title="React Monorepo" type="tutorial" isExternal="true" url="/tutorials/2-react-monorepo/1r-introduction/1-welcome" icon="reactMono" /%} {% link-card title="React Monorepo" type="tutorial" url="/getting-started/tutorials/react-monorepo-tutorial" icon="reactMono" /%}
{% link-card title="Angular Monorepo" type="tutorial" isExternal="true" url="/tutorials/3-angular-monorepo/1a-introduction/1-welcome" icon="angularMono" /%} {% link-card title="Angular Monorepo" type="tutorial" url="/getting-started/tutorials/angular-monorepo-tutorial" icon="angularMono" /%}
{% link-card title="Gradle Monorepo" type="tutorial" isExternal="true" url="/tutorials/4-gradle/1g-introduction/1-welcome" icon="gradle" /%} {% link-card title="Gradle Monorepo" type="tutorial" url="/getting-started/tutorials/gradle-tutorial" icon="gradle" /%}
{% /cards %} {% /cards %}

View File

@ -41,7 +41,7 @@ Here's a quick side-by-side overview comparing the features between the Angular
| Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ | | Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ |
| Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ | | Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ |
| Support for single-project Workspaces | ✅ | ✅ | | Support for single-project Workspaces | ✅ | ✅ |
| First-Class [Monorepo Support](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) | ❌\* | ✅ | | First-Class [Monorepo Support](/getting-started/tutorials/angular-monorepo-tutorial) | ❌\* | ✅ |
| [Enforced Module Boundaries](/features/enforce-module-boundaries) | ❌ | ✅ | | [Enforced Module Boundaries](/features/enforce-module-boundaries) | ❌ | ✅ |
| Interactive [Project Graph](/features/explore-graph) | ❌ | ✅ | | Interactive [Project Graph](/features/explore-graph) | ❌ | ✅ |
| Task Graph | ❌ | ✅ | | Task Graph | ❌ | ✅ |
@ -411,4 +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: You can learn more about Angular & Nx by following our dedicated tutorials:
- [Tutorial: Building Angular Apps in an Nx Monorepo](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) - [Tutorial: Building Angular Apps in an Nx Monorepo](/getting-started/tutorials/angular-monorepo-tutorial)

View File

@ -11,7 +11,7 @@ powering Nx underneath. As a result, Lerna gets all the modern features such as
on [https://lerna.js.org/upgrade](https://lerna.js.org/upgrade). on [https://lerna.js.org/upgrade](https://lerna.js.org/upgrade).
{% /callout %} {% /callout %}
Nx has first-class support for [monorepos](/tutorials/1-ts-packages/1t-introduction/1-welcome). If you have Nx has first-class support for [monorepos](/getting-started/tutorials/typescript-packages-tutorial). If you have
an existing NPM/Yarn or PNPM-based monorepo setup, you can easily add Nx to get an existing NPM/Yarn or PNPM-based monorepo setup, you can easily add Nx to get
- fast [task scheduling](/features/run-tasks) - fast [task scheduling](/features/run-tasks)

View File

@ -46,7 +46,7 @@ nx add @nx/angular
This will install the correct version of `@nx/angular`. This will install the correct version of `@nx/angular`.
{% callout type="note" title="Angular Tutorial" %} {% callout type="note" title="Angular Tutorial" %}
For a full tutorial experience, follow the [Angular Monorepo Tutorial](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) For a full tutorial experience, follow the [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
{% /callout %} {% /callout %}
## Using the Angular Plugin ## Using the Angular Plugin
@ -113,7 +113,7 @@ nx g @nx/angular:service apps/appName/src/lib/my-service/my-service
## More Documentation ## More Documentation
- [Angular Monorepo Tutorial](/tutorials/3-angular-monorepo/1a-introduction/1-welcome) - [Angular Monorepo Tutorial](/getting-started/tutorials/angular-monorepo-tutorial)
- [Migrating from the Angular CLI](/recipes/angular/migration/angular) - [Migrating from the Angular CLI](/recipes/angular/migration/angular)
- [Setup Module Federation with Angular and Nx](/concepts/module-federation/faster-builds-with-module-federation) - [Setup Module Federation with Angular and Nx](/concepts/module-federation/faster-builds-with-module-federation)
- [Using Tailwind CSS with Angular projects](/recipes/angular/using-tailwind-css-with-angular-projects) - [Using Tailwind CSS with Angular projects](/recipes/angular/using-tailwind-css-with-angular-projects)

View File

@ -19,7 +19,7 @@ It provides:
To create a new workspace with React, run `npx create-nx-workspace@latest --preset=react-standalone`. To create a new workspace with React, run `npx create-nx-workspace@latest --preset=react-standalone`.
{% callout type="note" title="React Tutorial" %} {% callout type="note" title="React Tutorial" %}
For a full tutorial experience, follow the [React Monorepo Tutorial](/tutorials/2-react-monorepo/1r-introduction/1-welcome) For a full tutorial experience, follow the [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
{% /callout %} {% /callout %}
### Installation ### Installation
@ -135,7 +135,7 @@ The library in `dist` is publishable to npm or a private registry.
## More Documentation ## More Documentation
- [React Monorepo Tutorial](/tutorials/2-react-monorepo/1r-introduction/1-welcome) - [React Monorepo Tutorial](/getting-started/tutorials/react-monorepo-tutorial)
- [Using Cypress](/nx-api/cypress) - [Using Cypress](/nx-api/cypress)
- [Using Jest](/nx-api/jest) - [Using Jest](/nx-api/jest)
- [Using Storybook](/recipes/storybook/overview-react) - [Using Storybook](/recipes/storybook/overview-react)

View File

@ -5,7 +5,11 @@
- [Installation](/getting-started/installation) - [Installation](/getting-started/installation)
- [Why Nx?](/getting-started/why-nx) - [Why Nx?](/getting-started/why-nx)
- [Editor Setup](/getting-started/editor-setup) - [Editor Setup](/getting-started/editor-setup)
- [Tutorials](/tutorials) - [Tutorials](/getting-started/tutorials)
- [TypeScript Monorepo](/getting-started/tutorials/typescript-packages-tutorial)
- [React Monorepo](/getting-started/tutorials/react-monorepo-tutorial)
- [Angular Monorepo](/getting-started/tutorials/angular-monorepo-tutorial)
- [Gradle Monorepo](/getting-started/tutorials/gradle-tutorial)
- [Features](/features) - [Features](/features)
- [Run Tasks](/features/run-tasks) - [Run Tasks](/features/run-tasks)
- [Cache Task Results](/features/cache-task-results) - [Cache Task Results](/features/cache-task-results)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,437 @@
---
title: 'Gradle Tutorial'
description: In this tutorial you'll add Nx to an existing Gradle repo
---
# Gradle Tutorial
In this tutorial, you'll learn how to add Nx to a repository with an existing Gradle setup.
What will you learn?
- how to add Nx to a Gradle project
- how to run a single task (i.e. serve your app) or run multiple tasks in parallel
- how to leverage code generators to scaffold components
- how to modularize your codebase and impose architectural constraints for better maintainability
- [how to speed up CI with Nx Cloud ⚡](#fast-ci)
## Prerequisites
Make sure that you have [Gradle](https://gradle.org/) installed on your system.
Consult [Gradle's installation guide](https://docs.gradle.org/current/userguide/installation.html) for instruction that
are specific to your operating system.
To verify that Gradle was installed correctly, run this command:
```shell
gradle --version
```
To streamline this tutorial, we'll install Nx globally on your system. You can use Homebrew (Mac only) or a manually installed Node version (any OS).
{% tabs %}
{% tab label="Homebrew" %}
Make sure [Homebrew is installed](https://brew.sh/), then install Nx globally with these commands:
```shell
brew tap nrwl/nx
brew install nx
```
{% /tab %}
{% tab label="Node" %}
Install node from the [NodeJS website](https://nodejs.org/en/download), then install Nx globally with this command:
```shell
npm install --global nx
```
{% /tab %}
{% /tabs %}
## Getting Started
This tutorial picks up where [Spring framework](https://spring.io/)'s guide for [Multi-Module Projects](https://spring.io/guides/gs/multi-module) leaves off.
Fork [the sample repository](https://github.com/nrwl/gradle-tutorial/fork), and then clone it on your local machine:
```shell
git clone https://github.com/<your-username>/gradle-tutorial.git
```
The Multi-Module Spring Tutorial left us with 2 projects:
- The main `application` project which contains the Spring `DemoApplication`
- A `library` project which contains a Service used in the `DemoApplication`
You can see the above 2 projects by running `./gradlew projects`
```text {% command="./gradlew projects" %}
> Task :projects
------------------------------------------------------------
Root project 'gradle-tutorial'
------------------------------------------------------------
Root project 'gradle-tutorial'
+--- Project ':application'
\--- Project ':library'
```
## Add Nx
Nx is a build system with built in tooling and advanced CI capabilities. It helps you maintain and scale monorepos,
both locally and on CI. We will explore the features of Nx in this tutorial by adding it to the Gradle workspace above.
To add Nx, run
```shell {% path="~/gradle-tutorial" %}
npx nx@latest init
```
This command will download the latest version of Nx and help set up your repository to take advantage of it. Nx will
also detect Gradle is used in the repo so it will propose adding the `@nx/gradle` plugin to integrate Gradle with Nx.
Select the plugin and continue with the setup.
Similar to Gradle, Nx can be run with the `nx` or `nx.bat` executables. We will learn about some of the Nx commands in
the following sections.
## Explore Your Workspace
Like Gradle, Nx understands your workspace as a graph of projects. Nx uses this graph for many things which we will
learn about in following sections. To visualize this graph in your browser, Run the following command and click the
"Show all projects" button in the left sidebar.
You will recognize that the projects which are shown, are the same projects which Gradle shows.
The `@nx/gradle` plugin reflects the graph of projects in Gradle into the Nx Project Graph. As projects
are created, deleted, and change their dependencies, Nx will automatically recalculate the graph. Exploring this graph
visually is vital to understanding how your code is structured and how Nx and Gradle behaves.
{% tabs %}
{% tab label="Mac/Linux" %}
```shell
./nx graph
```
{% /tab %}
{% tab label="Windows" %}
```shell
./nx.bat graph
```
{% /tab %}
{% /tabs %}
{% graph title="Gradle Projects" height="200px" jsonFile="shared/tutorials/gradle-project-graph.json" %}
{% /graph %}
## Running Tasks
Nx is a task runner built for monorepos. It can run a single task for a single project, a task for all projects, and
even intelligently run a subset of tasks based on the changes you've made in your repository. Nx also has sophisticated
computation caching to reuse the results of tasks. We will explore how Nx adds to the task running Gradle provides.
Before we start running tasks, let's explore the tasks available for the `application` project. The `@nx/gradle` plugin
that we've installed reflects Gradle's tasks to Nx, which allows it to run any of the Gradle tasks defined for that project. You can view the available tasks either through [Nx Console](/getting-started/editor-setup) or from the terminal:
```shell {% path="~/gradle-tutorial" %}
./nx show project application --web
```
{% project-details title="Project Details View" jsonFile="shared/tutorials/gradle-pdv.json" expandedTargets=["build"] height="520px" %}
{% /project-details %}
The Nx command to run the `build` task for the `application` project is:
```shell
./nx run application:build
```
When Nx runs a Gradle task, it hands off the execution of that task to Gradle, so all task dependencies and
configuration settings in the Gradle configuration are still respected.
By running the task via Nx, however, the task computation was cached for reuse. Now, running `./nx run application:build`
again, will complete almost instantly as the result from the previous execution will be used.
```{% command="./nx run application:build" %}
✔ 1/1 dependent project tasks succeeded [1 read from cache]
Hint: you can run the command with --verbose to see the full dependent project outputs
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
> nx run application:classes [existing outputs match the cache, left as is]
> ./gradlew :application:classes
> Task :library:compileJava UP-TO-DATE
> Task :library:processResources NO-SOURCE
> Task :library:classes UP-TO-DATE
> Task :library:jar UP-TO-DATE
> Task :application:compileJava UP-TO-DATE
> Task :application:processResources UP-TO-DATE
> Task :application:classes UP-TO-DATE
BUILD SUCCESSFUL in 647ms
4 actionable tasks: 4 up-to-date
> nx run application:build [existing outputs match the cache, left as is]
> ./gradlew :application:build
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.5/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD SUCCESSFUL in 768ms
9 actionable tasks: 1 executed, 8 up-to-date
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
NX Successfully ran target build for project application and 3 tasks it depends on (30ms)
Nx read the output from the cache instead of running the command for 4 out of 4 tasks.
```
Now that we've run one task, let's run all the `build` tasks in the repository with the Nx `run-many` command. This is similar to Gradle's `./gradlew build` command.
```{% command="./nx run-many -t build" %}
✔ nx run library:classes [existing outputs match the cache, left as is]
✔ nx run library:build [existing outputs match the cache, left as is]
✔ nx run application:classes [existing outputs match the cache, left as is]
✔ nx run application:build [existing outputs match the cache, left as is]
✔ nx run gradle-tutorial:classes (1s)
✔ nx run gradle-tutorial:build (1s)
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
NX Successfully ran target build for 3 projects and 3 tasks they depend on (2s)
Nx read the output from the cache instead of running the command for 4 out of 6 tasks.
```
Again, because Nx cached the tasks when the application was built, most of the tasks here were near instant. The only
ones which needed to be done is the root project's build. Running the command one more time, will be near instant as
then all the tasks will be restored from the cache.
## Run Tasks for Affected Projects
Nx doesn't just cache your task results, it can also [eliminate the need to run unnecessary tasks](/ci/features/affected).
First, commit any outstanding changes to the `main` branch locally:
```shell
git commit -am "changes"
```
Next make a small change to the `application` code:
```java {% fileName="application/src/main/java/com/example/multimodule/application/DemoApplication.java" highlightLines=[21] %}
package com.example.multimodule.application;
import com.example.multimodule.service.MyService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication(scanBasePackages = "com.example.multimodule")
@RestController
public class DemoApplication {
private final MyService myService;
public DemoApplication(MyService myService) {
this.myService = myService;
}
@GetMapping("/")
public String home() {
return myService.message() + " changed!";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
```
As a developer, we know that this change only affects the `application` project, not the `library` project. We would
run `./nx run application:test` to verify our changes. In CI, teams often run all test tasks rerunning
the `library:test` task unnecessarily.
For a repository with only a few projects, you can manually calculate which projects are affected. As the repository grows, it becomes critical to have a tool like Nx that understands the project dependency graph and eliminates wasted time in CI.
The `./nx affected` command solves this problem. Nx uses its project graph in conjunction with git history to only run
tasks for projects that may have been affected by the changes that you made.
To run the `test` tasks for projects affected by this change, run:
```shell
./nx affected -t test
```
Notice that this command does not run the `test` task for the `library` project, since it could not have been affected by the code change.
## Fast CI ⚡ {% highlightColor="green" %}
{% callout type="check" title="Repository with Nx" %}
Make sure you have completed the previous sections of this tutorial before starting this one. If you want a clean starting point, you can check out the [reference code](https://github.com/nrwl/nx-recipes/tree/main/gradle) as a starting point.
{% /callout %}
This tutorial walked you through how Nx can improve the local development experience, but the biggest difference Nx makes is in CI. As repositories get bigger, making sure that the CI is fast, reliable and maintainable can get very challenging. Nx provides a solution.
- Nx reduces wasted time in CI with the [`affected` command](/ci/features/affected).
- Nx Replay's [remote caching](/ci/features/remote-cache) will reuse task artifacts from different CI executions making sure you will never run the same computation twice.
- Nx Agents [efficiently distribute tasks across machines](/ci/concepts/parallelization-distribution) ensuring constant CI time regardless of the repository size. The right number of machines is allocated for each PR to ensure good performance without wasting compute.
- Nx Atomizer [automatically splits](/ci/features/split-e2e-tasks) large e2e tests to distribute them across machines. Nx can also automatically [identify and rerun flaky e2e tests](/ci/features/flaky-tasks).
### Connect to Nx Cloud {% highlightColor="green" %}
Nx Cloud is a companion app for your CI system that provides remote caching, task distribution, e2e tests deflaking, better DX and more.
Now that we're working on the CI pipeline, it is important for your changes to be pushed to a GitHub repository.
1. Commit your existing changes with `git add . && git commit -am "updates"`
2. [Create a new GitHub repository](https://github.com/new)
3. Follow GitHub's instructions to push your existing code to the repository
Now connect your repository to Nx Cloud with the following command:
```shell
./nx connect
```
A browser window will open to register your repository in your [Nx Cloud](https://cloud.nx.app) account. The link is also printed to the terminal if the windows does not open, or you closed it before finishing the steps. The app will guide you to create a PR to enable Nx Cloud on your repository.
![](/shared/tutorials/nx-cloud-github-connect.avif)
Once the PR is created, merge it into your main branch.
![](/shared/tutorials/github-cloud-pr-merged.avif)
And make sure you pull the latest changes locally:
```shell
git pull
```
You should now have an `nxCloudId` property specified in the `nx.json` file.
### Create a CI Workflow {% highlightColor="green" %}
Let's create a branch to add a CI workflow.
```shell
git checkout -b add-workflow
```
And use the following command to generate a CI workflow file.
```shell
./nx generate ci-workflow --ci=github
```
This generator creates a `.github/workflows/ci.yml` file that contains a CI pipeline that will run the `lint`, `test`, `build` and `e2e` tasks for projects that are affected by any given PR. If you would like to also distribute tasks across multiple machines to ensure fast and reliable CI runs, uncomment the `nx-cloud start-ci-run` line.
The key lines in the CI pipeline are:
```yml {% fileName=".github/workflows/ci.yml" highlightLines=["21-24", "38-39"] %}
name: CI
on:
push:
branches:
- main
pull_request:
permissions:
actions: read
contents: read
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
filter: tree:0
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Uncomment this line to enable task distribution
# - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-jvm" --stop-agents-after="build"
- name: Set up JDK 21 for x64
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
architecture: x64
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- uses: nrwl/nx-set-shas@v4
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- run: ./nx affected -t test build
```
### Open a Pull Request {% highlightColor="green" %}
Commit the changes and open a new PR on GitHub.
```shell
git add .
git commit -m 'add CI workflow file'
git push origin add-workflow
```
When you view the PR on GitHub, you will see a comment from Nx Cloud that reports on the status of the CI run.
![Nx Cloud report](/shared/tutorials/gradle-github-pr-cloud-report.avif)
The `See all runs` link goes to a page with the progress and results of tasks that were run in the CI pipeline.
![Gradle run details](/shared/tutorials/gradle-run-details.webp)
For more information about how Nx can improve your CI pipeline, check out one of these detailed tutorials:
- [Circle CI with Nx](/ci/intro/tutorials/circle)
- [GitHub Actions with Nx](/ci/intro/tutorials/github-actions)
## Summary
Now that you have added Nx to this sample Gradle repository, you have learned several ways that Nx can help your
organization:
- Nx reflects the Gradle graph into the Nx graph
- Nx's dependency graph visualisation helps you understand your codebase
- Nx caches task results and reuses them when the same task is rerun later
- Nx intelligently determines which tasks are `affected` by code changes to reduce waste in CI
- Nx Cloud provides remote caching and distributed task execution to speed up CI
## Next Steps
Connect with the rest of the Nx community with these resources:
- ⭐️ [Star us on GitHub](https://github.com/nrwl/nx) to show your support and stay updated on new releases!
- [Join the Official Nx Discord Server](https://go.nx.dev/community) to ask questions and find out the latest news about
Nx.
- [Follow Nx on Twitter](https://twitter.com/nxdevtools) to stay up to date with Nx news
- [Read our Nx blog](/blog)
- [Subscribe to our Youtube channel](https://www.youtube.com/@nxdevtools) for demos and Nx insights

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,505 @@
---
title: 'TypeScript Monorepo Tutorial'
description: In this tutorial you'll add Nx to an existing TypeScript repo
---
# TypeScript Monorepo Tutorial
In this tutorial, you'll learn how to add Nx to a repository with an existing TypeScript project. The starting repository uses [NPM workspaces](https://docs.npmjs.com/cli/using-npm/workspaces) for project linking and is configured to build with [TypeScript project references](https://www.typescriptlang.org/docs/handbook/project-references.html).
What will you learn?
- how to add Nx to the repository with a single command
- how to configure caching for your tasks
- how to configure a task pipeline
- how to configure projects automatically with Nx Plugins
- how to manage your releases with `nx release`
- [how to speed up CI with Nx Cloud ⚡](#fast-ci)
<!-- ## Final Source Code
Here's the source code of the final result for this tutorial.
{% github-repository url="https://github.com/nrwl/nx-recipes/tree/main/typescript-packages" /%} -->
<!-- {% youtube
src="https://www.youtube.com/embed/ZA9K4iT3ANc"
title="Nx NPM Workspaces Tutorial Walkthrough"
/%} -->
## Starting Repository
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=51" /%} -->
To get started, fork [the sample repository](https://github.com/nrwl/tuskydesign/fork) and clone it on your local machine:
```shell
git clone https://github.com/<your-username>/tuskydesign.git
```
The repository has three TypeScript packages under `packages/animals`, `packages/names` and `packages/zoo`. The `zoo` package uses `animals` and `names` to generate a random message. The root `package.json` has a `workspaces` property that tells NPM how to find the projects in the repository.
```json {% fileName="package.json" %}
{
"workspaces": ["packages/*"]
}
```
Because of this setting, when the install command is run at the root, the correct packages are installed for each project. NPM will create dedicated `node_modules` folders inside of each project folder where necessary.
```shell
npm install
```
Now let's try running some tasks. To build the `animals` package, use the `build` npm script:
```text {% command="npm run build -w @tuskdesign/animals" path="~/tuskydesigns" %}
> @tuskdesign/animals@1.2.0 build
> tsc --build tsconfig.lib.json
```
The repository is set up using [TypeScript project references](https://www.typescriptlang.org/docs/handbook/project-references.html) so building the `zoo` package will automatically build all its dependencies.
```text {% command="npm run build -w @tuskdesign/zoo" path="~/tuskydesigns" %}
> @tuskdesign/zoo@1.2.0 build
> tsc --build tsconfig.lib.json
```
To run the `zoo` package use the `serve` script:
```text {% command="npm run serve -w @tuskdesign/zoo" path="~/tuskydesigns" %}
> @tuskdesign/zoo@1.2.0 serve
> node dist/index.js
Bo the pig says oink!
```
Now that you have a basic understanding of the repository we're working with, let's see how Nx can help us.
## Smart Monorepo
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=170" /%} -->
Nx offers many features, but at its core, it is a task runner. Out of the box, it can cache your tasks and ensure those tasks are run in the correct order. After the initial set up, you can incrementally add on other features that would be helpful in your organization.
### Add Nx
To enable Nx in your repository, run a single command:
```shell {% path="~/tuskydesigns" %}
npx nx@latest init
```
This command will download the latest version of Nx and help set up your repository to take advantage of it.
First, the script will propose installing some plugins based on the packages that are being used in your repository.
- Deselect both proposed plugins so that we can explore what Nx provides without any plugins.
Second, the script asks a series of questions to help set up caching for you.
- `Which scripts need to be run in order?` - Choose `build`
- `Which scripts are cacheable?` - Choose `build` and `typecheck`
- `Does the "build" script create any outputs?` - Enter `dist`
- `Does the "typecheck" script create any outputs?` - Enter nothing
- `Would you like remote caching to make your build faster?` - Choose `Skip for now`
### Explore Your Workspace
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=250" /%} -->
If you run `nx graph` as instructed, you'll see the dependencies between your projects.
```shell {% path="~/tuskydesigns" %}
npx nx graph --focus=@tuskdesign/zoo
```
{% graph title="Tusk Design" height="200px" jsonFile="shared/tutorials/typescript-packages-project-graph.json" %}
{% /graph %}
Nx uses this graph to determine the order tasks are run and enforce module boundaries. You can also leverage this graph to gain an accurate understanding of the architecture of your codebase. Part of what makes this graph invaluable is that it is derived directly from your codebase, so it will never become out of date.
### Caching Pre-configured
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=285" /%} -->
Nx has been configured to run your `build`, `typecheck` and `lint` tasks. You can run a single task like this:
```shell {% path="~/tuskydesigns" %}
npx nx build @tuskdesign/zoo
```
Or all tasks with a certain name like this:
```shell {% path="~/tuskydesigns" %}
npx nx run-many -t typecheck
```
During the `init` script, Nx also configured caching for these tasks. You can see in the `nx.json` file that the `build`, `typecheck` and `lint` targets have the `cache` property set to `true` and the `build` target specifies that its output goes to the project's `dist` folder.
```json {% fileName="nx.json" %}
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/dist"],
"cache": true
},
"typecheck": {
"cache": true
},
"lint": {
"cache": true
}
},
"defaultBase": "main"
}
```
Try running `build` for the `zoo` app a second time:
```shell {% path="~/tuskydesigns" %}
npx nx build @tuskdesign/zoo
```
The first time `nx build` was run, it took about 1 second - just like running `npm run build`. But the second time you run `nx build`, it completes instantly and displays this message:
```text
Nx read the output from the cache instead of running the command for 3 out of 3 tasks.
```
You can see the same caching behavior working when you run `npx nx typecheck`.
### Use Task Pipelines
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=358" /%} -->
You may be wondering why the caching message in the previous section mentioned 3 tasks when you only ran the `build` task from the terminal. When we said that `build` tasks must be run in order during the setup script, Nx created a simple task pipeline. You can see the configuration for it in the `nx.json` file:
```json {% fileName="nx.json" %}
{
"targetDefaults": {
"build": {
"dependsOn": ["^build"]
}
}
}
```
This configuration means that if you run `build` on any project, Nx will first run `build` for the dependencies of that project and then run `build` on the project itself. The `^build` text means "the `build` tasks of the project's dependencies." You can visualize this in the Nx graph by selecting the `Tasks` dropdown in the top left and clicking `Show all tasks`:
```shell {% path="~/tuskydesigns" %}
npx nx graph
```
Alternatively, you can pass the `--graph` option to the run command to inspect the task graph.
```shell {% path="~/tuskydesigns" %}
npx nx run @tuskdesign/zoo:build --graph
```
{% graph height="200px" title="Build Task Pipeline" type="task" jsonFile="shared/tutorials/typescript-packages-build-tasks1.json" %}
{% /graph %}
### Create a Task Pipeline
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=450" /%} -->
You may have noticed in the `packages/zoo/package.json` file, there is a `serve` script that expects the `build` task to already have created the `dist` folder. Let's set up a task pipeline that will guarantee that the project's `build` task has been run.
```json {% fileName="nx.json" highlightLines=[5] %}
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"targetDefaults": {
"serve": {
"dependsOn": ["build"]
},
"build": {
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/dist"],
"cache": true
},
"typecheck": {
"cache": true
}
},
"defaultBase": "main"
}
```
The `serve` target's `dependsOn` line makes Nx run the `build` task for the current project before running the current project's `build` task. Now `nx serve` will run the `build` task before running the `serve` task.
### Use Nx Plugins to Enhance Your Workspace
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=507" /%} -->
We mentioned earlier that this repository is using TypeScript project references defined in the `tsconfig.json` files to incrementally build each project so that the output is available for other projects in the repository. In order for this feature to work, the `references` section in the `tsconfig.json` files for each project need to accurately reflect the actual dependencies of that project. This can be difficult to maintain, but Nx already knows the dependencies of every project and you can use the `@nx/js` plugin to automatically keep the TypeScript project references in sync with the code base.
Nx plugins can:
- automatically configure caching for you, including inputs and outputs based on the underlying tooling configuration
- infer tasks that can be run on a project because of the tooling present
- keep tooling configuration in sync with the structure of your codebase
- provide code generators to help scaffold out projects
- automatically keep the tooling versions and configuration files up to date
For this tutorial, we'll focus on inferring tasks and keeping tooling configuration in sync.
First, let's remove the existing `build` and `typecheck` scripts from each project's `package.json` files to allow the `@nx/js` plugin to infer those tasks for us.
```json {% fileName="packages/animals/package.json" %}
{
"scripts": {}
}
```
```json {% fileName="packages/names/package.json" %}
{
"scripts": {}
}
```
```json {% fileName="packages/zoo/package.json" %}
{
"scripts": {
"serve": "node dist/index.js"
}
}
```
Now let's add the `@nx/js` plugin:
```{% command="npx nx add @nx/js" path="~/tuskydesign" %}
✔ Installing @nx/js...
✔ Initializing @nx/js...
NX Generating @nx/js:init
UPDATE nx.json
UPDATE package.json
NX Package @nx/js added successfully.
```
The `nx add` command installs the version of the plugin that matches your repo's Nx version and runs that plugin's initialization script. For `@nx/js`, the initialization script registers the plugin in the `plugins` array of `nx.json`. The registered plugin automatically infers `build` and `typecheck` tasks for any project with a `tsconfig.json` file. Open the project details view for the `zoo` package and look at the `build` task.
```shell {% path="~/tuskydesigns" %}
npx nx show project @tuskdesign/zoo
```
{% project-details title="Project Details View" jsonFile="shared/tutorials/typescript-packages-pdv.json" %}
{% /project-details %}
Notice that the `inputs` that are inferred for the `build` task match the `include` and `exclude` settings in the `tsconfig.lib.json` file. As those settings are changed, the cache `inputs` will automatically update to the correct values.
The `build` task also has a [sync generator](/concepts/sync-generators) defined. The `@nx/js:typescript-sync` generator will automatically update the `references` property in the `tsconfig.json` files across the repository to match the actual dependencies in your code.
Let's see this behavior in action by extracting some common code into a new `util` library.
First, create a library with `@nx/js:lib` generator:
```shell
nx g @nx/js:lib packages/util
```
Set the bundler to `tsc`, the linter to `none` and the unit test runner to `none`.
Now we can move the `getRandomItem` function from `packages/names/names.ts` and `packages/animals/animals.ts` into the `packages/util/src/lib/util.ts` file.
```ts {% fileName="packages/util/src/lib/util.ts" %}
export function getRandomItem<T>(arr: T[]): T {
return arr[Math.floor(Math.random() * arr.length)];
}
```
```ts {% fileName="packages/animals/animals.ts" %}
import { getRandomItem } from '@tuskdesign/util';
// ...
```
```ts {% fileName="packages/names/names.ts" %}
import { getRandomItem } from '@tuskdesign/util';
// ...
```
Now if you run the build, Nx will notice that the TypeScript project references need to be updated and ask your permission to update them.
```text {% command="nx build @tuskdesign/zoo" path="~/tuskydesigns" %}
NX The workspace is out of sync
[@nx/js:typescript-sync]: Some TypeScript configuration files are missing project references to the projects they depend on or contain outdated project references.
This will result in an error in CI.
? Would you like to sync the identified changes to get your workspace up to date? …
Yes, sync the changes and run the tasks
No, run the tasks without syncing the changes
```
Allow the sync to happen and you'll see that the `tsconfig.json` and `tsconfig.lib.json` files have been updated to include references to the new `util` library. With this system in place, no matter how your codebase changes, the TypeScript project references will always be correct.
### Checkpoint
At this point, the repository is still using all the same tools to run tasks, but now Nx runs those tasks in a smarter way. The tasks are efficiently cached so that there is no repeated work and the cache configuration settings are automatically synced with your tooling configuration files by Nx plugins. Also, any task dependencies are automatically executed whenever needed because we configured task pipelines for the projects.
Open up the task graph for `zoo` app's `serve` task again to see the changes.
```shell {% path="~/tuskydesigns" %}
npx nx run @tuskdesign/zoo:serve --graph
```
{% graph height="200px" title="Build Task Pipeline" type="task" jsonFile="shared/tutorials/typescript-packages-build-tasks2.json" %}
{% /graph %}
## Manage Releases
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=713" /%} -->
If you decide to publish the `animals` or `names` packages on NPM, Nx can also help you [manage the release process](/features/manage-releases). Release management involves updating the version of your package, populating a changelog, and publishing the new version to the NPM registry.
First you'll need to define which projects Nx should manage releases for by setting the `release.projects` property in `nx.json`:
```json {% fileName="nx.json" %}
{
"release": {
"projects": ["packages/*"]
}
}
```
Now you're ready to use the `nx release` command to publish the `animals` and `names` packages. The first time you run `nx release`, you need to add the `--first-release` flag so that Nx doesn't try to find the previous version to compare against. It's also recommended to use the `--dry-run` flag until you're sure about the results of the `nx release` command, then you can run it a final time without the `--dry-run` flag.
To preview your first release, run:
```shell
npx nx release --first-release --dry-run
```
The command will ask you a series of questions and then show you what the results would be. Once you are happy with the results, run it again without the `--dry-run` flag:
```shell
npx nx release --first-release
```
After this first release, you can remove the `--first-release` flag and just run `nx release --dry-run`. There is also a [dedicated feature page](/features/manage-releases) that goes into more detail about how to use the `nx release` command.
## Fast CI ⚡ {% highlightColor="green" %}
<!-- {% video-link link="https://youtu.be/ZA9K4iT3ANc?t=821" /%} -->
{% callout type="check" title="Forked repository with Nx" %}
Make sure you have completed the previous sections of this tutorial before starting this one. If you want a clean starting point, you can fork the [sample repository with Nx already added](https://github.com/nrwl/nx-recipes/tree/main/typescript-packages).
{% /callout %}
So far in this tutorial you've seen how Nx improves the local development experience, but the biggest difference Nx makes is in CI. As repositories get bigger, making sure that the CI is fast, reliable and maintainable can get very challenging. Nx provides a solution.
- Nx reduces wasted time in CI with the [`affected` command](/ci/features/affected).
- Nx Replay's [remote caching](/ci/features/remote-cache) will reuse task artifacts from different CI executions making sure you will never run the same computation twice.
- Nx Agents [efficiently distribute tasks across machines](/ci/features/distribute-task-execution) ensuring constant CI time regardless of the repository size. The right number of machines is allocated for each PR to ensure good performance without wasting compute.
- Nx Atomizer [automatically splits](/ci/features/split-e2e-tasks) large e2e tests to distribute them across machines. Nx can also automatically [identify and rerun flaky e2e tests](/ci/features/flaky-tasks).
### Connect to Nx Cloud {% highlightColor="green" %}
Nx Cloud is a companion app for your CI system that provides remote caching, task distribution, e2e tests deflaking, better DX and more.
Now that we're working on the CI pipeline, it is important for your changes to be pushed to a GitHub repository.
1. Commit your existing changes with `git add . && git commit -am "updates"`
2. Push your changes to your forked GitHub repository with `git push`
Now connect your repository to Nx Cloud with the following command:
```shell
npx nx connect
```
A browser window will open to register your repository in your [Nx Cloud](https://cloud.nx.app) account. The link is also printed to the terminal if the windows does not open, or you closed it before finishing the steps. The app will guide you to create a PR to enable Nx Cloud on your repository.
![](/shared/tutorials/nx-cloud-github-connect.avif)
Once the PR is created, merge it into your main branch.
![](/shared/tutorials/github-cloud-pr-merged.avif)
And make sure you pull the latest changes locally:
```shell
git pull
```
You should now have an `nxCloudId` property specified in the `nx.json` file.
### Create a CI Workflow {% highlightColor="green" %}
Use the following command to generate a CI workflow file.
```shell
npx nx generate ci-workflow --ci=github
```
This generator creates a `.github/workflows/ci.yml` file that contains a CI pipeline that will run the `lint`, `test`, `build` and `e2e` tasks for projects that are affected by any given PR. If you would like to also distribute tasks across multiple machines to ensure fast and reliable CI runs, uncomment the `nx-cloud start-ci-run` line and have the `nx affected` line run the `e2e-ci` task instead of `e2e`.
The key lines in the CI pipeline are:
```yml {% fileName=".github/workflows/ci.yml" highlightLines=["10-14", "21-23"] %}
name: CI
# ...
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
filter: tree:0
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Uncomment this line to enable task distribution
# - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci"
- uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'
- run: npm ci --legacy-peer-deps
- uses: nrwl/nx-set-shas@v4
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
# When you enable task distribution, run the e2e-ci task instead of e2e
- run: npx nx affected -t lint test build e2e
```
### Open a Pull Request {% highlightColor="green" %}
Commit the changes and open a new PR on GitHub.
```shell
git add .
git commit -m 'add CI workflow file'
git push origin add-workflow
```
When you view the PR on GitHub, you will see a comment from Nx Cloud that reports on the status of the CI run.
![Nx Cloud report](/shared/tutorials/github-pr-cloud-report.avif)
The `See all runs` link goes to a page with the progress and results of tasks that were run in the CI pipeline.
![Run details](/shared/tutorials/nx-cloud-run-details.avif)
For more information about how Nx can improve your CI pipeline, check out one of these detailed tutorials:
- [Circle CI with Nx](/ci/intro/tutorials/circle)
- [GitHub Actions with Nx](/ci/intro/tutorials/github-actions)
## Next Steps
Connect with the rest of the Nx community with these resources:
- ⭐️ [Star us on GitHub](https://github.com/nrwl/nx) to show your support and stay updated on new releases!
- [Join the Official Nx Discord Server](https://go.nx.dev/community) to ask questions and find out the latest news about Nx.
- [Follow Nx on Twitter](https://twitter.com/nxdevtools) to stay up to date with Nx news
- [Read our Nx blog](/blog)
- [Subscribe to our Youtube channel](https://www.youtube.com/@nxdevtools) for demos and Nx insights

View File

@ -56,7 +56,7 @@ export default function NxDocumentation({
} }
export const getStaticPaths: GetStaticPaths = () => { export const getStaticPaths: GetStaticPaths = () => {
const reservedPaths = ['/ci', '/nx-api', '/changelog', '/tutorials']; const reservedPaths = ['/ci', '/nx-api', '/changelog'];
return { return {
paths: nxDocumentationApi paths: nxDocumentationApi
.getSlugsStaticDocumentPaths() .getSlugsStaticDocumentPaths()

View File

@ -62,7 +62,7 @@ export default function Tutorials(): JSX.Element {
<TutorialCard <TutorialCard
title="TypeScript Monorepo" title="TypeScript Monorepo"
type="Tutorial" type="Tutorial"
url="/tutorials/1-ts-packages/1t-introduction/1-welcome" url="/tutorials/1-ts-packages/1-introduction/1-welcome"
icon="jsMono" icon="jsMono"
/> />
<TutorialCard <TutorialCard
@ -80,7 +80,7 @@ export default function Tutorials(): JSX.Element {
<TutorialCard <TutorialCard
title="Gradle Monorepo" title="Gradle Monorepo"
type="Tutorial" type="Tutorial"
url="/tutorials/4-gradle/1g-introduction/1-welcome" url="/getting-started/tutorials/gradle-tutorial"
icon="gradle" icon="gradle"
/> />
</dl> </dl>

View File

@ -600,42 +600,42 @@ for (const path of oldAngularTutorialPaths) {
*/ */
const standaloneTutorialRedirects = { const standaloneTutorialRedirects = {
'/showcase/example-repos/react-nx': '/showcase/example-repos/react-nx':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-tutorial': '/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/react-tutorial': '/getting-started/tutorials/react-monorepo-tutorial',
'/react-tutorial/1-code-generation': '/react-tutorial/1-code-generation':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-tutorial/2-project-graph': '/react-tutorial/2-project-graph':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-tutorial/3-task-running': '/react-tutorial/3-task-running':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-tutorial/4-task-pipelines': '/react-tutorial/4-task-pipelines':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-tutorial/5-summary': '/react-tutorial/5-summary':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-standalone-tutorial': '/react-standalone-tutorial':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-standalone-tutorial/1-code-generation': '/react-standalone-tutorial/1-code-generation':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-standalone-tutorial/2-project-graph': '/react-standalone-tutorial/2-project-graph':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-standalone-tutorial/3-task-running': '/react-standalone-tutorial/3-task-running':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-standalone-tutorial/4-task-pipelines': '/react-standalone-tutorial/4-task-pipelines':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/react-standalone-tutorial/5-summary': '/react-standalone-tutorial/5-summary':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/angular-standalone-tutorial': '/angular-standalone-tutorial':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-standalone-tutorial/1-code-generation': '/angular-standalone-tutorial/1-code-generation':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-standalone-tutorial/2-project-graph': '/angular-standalone-tutorial/2-project-graph':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-standalone-tutorial/3-task-running': '/angular-standalone-tutorial/3-task-running':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-standalone-tutorial/4-task-pipelines': '/angular-standalone-tutorial/4-task-pipelines':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-standalone-tutorial/5-summary': '/angular-standalone-tutorial/5-summary':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
}; };
const packagesIndexes = { const packagesIndexes = {
@ -773,17 +773,17 @@ const conceptUrls = {
'/concepts/more-concepts/global-nx': '/concepts/more-concepts/global-nx':
'/getting-started/installation#installing-nx-globally', '/getting-started/installation#installing-nx-globally',
'/getting-started/package-based-repo-tutorial': '/getting-started/package-based-repo-tutorial':
'/tutorials/1-ts-packages/1t-introduction/1-welcome', '/getting-started/tutorials/typescript-packages-tutorial',
'/getting-started/tutorials/package-based-repo-tutorial': '/getting-started/tutorials/package-based-repo-tutorial':
'/tutorials/1-ts-packages/1t-introduction/1-welcome', '/getting-started/tutorials/typescript-packages-tutorial',
'/getting-started/integrated-repo-tutorial': '/getting-started/integrated-repo-tutorial':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/getting-started/tutorials/integrated-repo-tutorial': '/getting-started/tutorials/integrated-repo-tutorial':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/getting-started/react-standalone-tutorial': '/getting-started/react-standalone-tutorial':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/getting-started/angular-standalone-tutorial': '/getting-started/angular-standalone-tutorial':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/concepts/more-concepts/micro-frontend-architecture': '/concepts/more-concepts/micro-frontend-architecture':
'/concepts/module-federation/micro-frontend-architecture', '/concepts/module-federation/micro-frontend-architecture',
'/concepts/more-concepts/faster-builds-with-module-federation': '/concepts/more-concepts/faster-builds-with-module-federation':
@ -799,45 +799,35 @@ const conceptUrls = {
const nested5minuteTutorialUrls = { const nested5minuteTutorialUrls = {
'/tutorials/package-based-repo-tutorial': '/tutorials/package-based-repo-tutorial':
'/tutorials/1-ts-packages/1t-introduction/1-welcome', '/getting-started/tutorials/typescript-packages-tutorial',
'/getting-started/tutorials/npm-workspaces-tutorial': '/getting-started/tutorials/npm-workspaces-tutorial':
'/tutorials/1-ts-packages/1t-introduction/1-welcome', '/getting-started/tutorials/typescript-packages-tutorial',
'/tutorials/integrated-repo-tutorial': '/tutorials/integrated-repo-tutorial':
'/getting-started/tutorials/integrated-repo-tutorial', '/getting-started/tutorials/integrated-repo-tutorial',
'/tutorials/react-standalone-tutorial': '/tutorials/react-standalone-tutorial':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/getting-started/tutorials/react-standalone-tutorial': '/getting-started/tutorials/react-standalone-tutorial':
'/tutorials/2-react-monorepo/1r-introduction/1-welcome', '/getting-started/tutorials/react-monorepo-tutorial',
'/tutorials/angular-standalone-tutorial': '/tutorials/angular-standalone-tutorial':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/getting-started/tutorials/angular-standalone-tutorial': '/getting-started/tutorials/angular-standalone-tutorial':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/getting-started/tutorials/vue-standalone-tutorial': '/getting-started/tutorials/vue-standalone-tutorial':
'/getting-started/tutorials', '/getting-started/tutorials',
'/tutorials/node-server-tutorial': '/getting-started/tutorials', '/tutorials/node-server-tutorial': '/getting-started/tutorials',
'/angular-tutorial': '/angular-tutorial': '/getting-started/tutorials/angular-monorepo-tutorial',
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome',
'/angular-tutorial/1-code-generation': '/angular-tutorial/1-code-generation':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/getting-started/angular-monorepo-tutorial': '/getting-started/angular-monorepo-tutorial':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-tutorial/2-project-graph': '/angular-tutorial/2-project-graph':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-tutorial/3-task-running': '/angular-tutorial/3-task-running':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-tutorial/4-workspace-optimization': '/angular-tutorial/4-workspace-optimization':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/angular-tutorial/5-summary': '/angular-tutorial/5-summary':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome', '/getting-started/tutorials/angular-monorepo-tutorial',
'/getting-started/tutorials': '/tutorials',
'/getting-started/tutorials/typescript-packages-tutorial':
'/tutorials/1-ts-packages/1t-introduction/1-welcome',
'/getting-started/tutorials/react-monorepo-tutorial':
'/tutorials/2-react-monorepo/1a-introduction/1-welcome',
'/getting-started/tutorials/angular-monorepo-tutorial':
'/tutorials/3-angular-monorepo/1a-introduction/1-welcome',
'/getting-started/tutorials/gradle-tutorial':
'/tutorials/4-gradle/1a-introduction/1-welcome',
}; };
const pluginUrls = { const pluginUrls = {

View File

@ -1,2 +0,0 @@
// TODO(isaac): nx build tutorial is caching when there are template changes
// Bust: 3

View File

@ -15,10 +15,8 @@ export function applyFileChangesPlugin(): ExpressiveCodePlugin {
applyFileChangesTexts, applyFileChangesTexts,
(codeBlock, isTerminal) => (codeBlock, isTerminal) =>
!isTerminal && !isTerminal &&
['solution:', 'file:'].some( ['solution:', 'file:'].some((prefix) =>
(prefix) => codeBlock.metaOptions.getString('path')?.startsWith(prefix)
codeBlock.metaOptions.getString('path')?.startsWith(prefix) &&
!codeBlock.metaOptions.getBoolean('no-apply')
), ),
(codeBlock, _) => { (codeBlock, _) => {
return { return {

View File

@ -17,8 +17,7 @@ export function runInTerminalPlugin(): ExpressiveCodePlugin {
'runInTerminal', 'runInTerminal',
svg, svg,
runInTerminalTexts, runInTerminalTexts,
(codeBlock, isTerminal) => (_, isTerminal) => isTerminal,
isTerminal && !codeBlock.metaOptions.getBoolean('no-run'),
(codeBlock, _) => { (codeBlock, _) => {
// remove comment lines starting with `#` from terminal frames // remove comment lines starting with `#` from terminal frames
let code = codeBlock.code.replace(/(?<=^|\n)\s*#.*($|\n+)/g, '').trim(); let code = codeBlock.code.replace(/(?<=^|\n)\s*#.*($|\n+)/g, '').trim();

View File

@ -78,7 +78,7 @@ export function GlobalCustomizations() {
// Apply file changes // Apply file changes
async function applyFileChanges(e: any) { async function applyFileChanges(e: any) {
const { filepath } = e.detail; const { filepath } = e.detail;
if (!filepath || !(tutorialStore as any)._lessonSolution[filepath]) { if (!filepath) {
return; return;
} }
tutorialStore.updateFile( tutorialStore.updateFile(

View File

@ -13,7 +13,7 @@ previews:
If you run `nx graph` as instructed, you'll see the dependencies between your projects. If you run `nx graph` as instructed, you'll see the dependencies between your projects.
```shell {% path="~/tuskydesigns" %} ```shell {% path="~/tuskydesigns" %}
nx graph --focus=@tuskdesign/zoo npx nx graph --focus=@tuskdesign/zoo
``` ```
Nx uses this graph to determine the order tasks are run and enforce module boundaries. You can also leverage this graph to gain an accurate understanding of the architecture of your codebase. Part of what makes this graph invaluable is that it is derived directly from your codebase, so it will never become out of date. Nx uses this graph to determine the order tasks are run and enforce module boundaries. You can also leverage this graph to gain an accurate understanding of the architecture of your codebase. Part of what makes this graph invaluable is that it is derived directly from your codebase, so it will never become out of date.

View File

@ -19,5 +19,5 @@ The `serve` target's `dependsOn` line makes Nx run the `build` task for the curr
Now `nx serve` will run the `build` task before running the `serve` task. Now `nx serve` will run the `build` task before running the `serve` task.
```shell ```shell
nx serve zoo npx nx serve zoo
``` ```

View File

@ -41,7 +41,7 @@ First, let's remove the existing `build` and `typecheck` scripts from each proje
Now let's add the `@nx/js` plugin: Now let's add the `@nx/js` plugin:
```shell ```shell
nx add @nx/js npx nx add @nx/js
``` ```
Your output should look like this: Your output should look like this:
@ -62,7 +62,7 @@ The `nx add` command installs the version of the plugin that matches your repo's
Open the project details view for the `zoo` package and look at the `build` task. Open the project details view for the `zoo` package and look at the `build` task.
```shell ```shell
nx show project @tuskdesign/zoo npx nx show project @tuskdesign/zoo
``` ```
Notice that the `inputs` that are inferred for the `build` task match the `include` and `exclude` settings in the `tsconfig.lib.json` file. As those settings are changed, the cache `inputs` will automatically update to the correct values. Notice that the `inputs` that are inferred for the `build` task match the `include` and `exclude` settings in the `tsconfig.lib.json` file. As those settings are changed, the cache `inputs` will automatically update to the correct values.

View File

@ -16,7 +16,7 @@ At this point, the repository is still using all the same tools to run tasks, bu
Open up the task graph for `zoo` app's `serve` task again to see the changes. Open up the task graph for `zoo` app's `serve` task again to see the changes.
```shell {% path="~/tuskydesigns" %} ```shell {% path="~/tuskydesigns" %}
nx run @tuskdesign/zoo:serve --graph npx nx run @tuskdesign/zoo:serve --graph
``` ```
The rest of this tutorial covers managing releases and setting up CI, which both require you to have a local copy of the repository. Click the "Download Repository" button and extract the zip file on your local machine before moving to the next section. The rest of this tutorial covers managing releases and setting up CI, which both require you to have a local copy of the repository. Click the "Download Repository" button and extract the zip file on your local machine before moving to the next section.

View File

@ -32,13 +32,13 @@ Now you're ready to use the `nx release` command to publish the `animals` and `n
To preview your first release, run: To preview your first release, run:
```shell ```shell
nx release --first-release --dry-run npx nx release --first-release --dry-run
``` ```
The command will ask you a series of questions and then show you what the results would be. Once you are happy with the results, run it again without the `--dry-run` flag: The command will ask you a series of questions and then show you what the results would be. Once you are happy with the results, run it again without the `--dry-run` flag:
```shell ```shell
nx release --first-release npx nx release --first-release
``` ```
After this first release, you can remove the `--first-release` flag and just run `nx release --dry-run`. There is also a [dedicated feature page](/features/manage-releases) that goes into more detail about how to use the `nx release` command. After this first release, you can remove the `--first-release` flag and just run `nx release --dry-run`. There is also a [dedicated feature page](/features/manage-releases) that goes into more detail about how to use the `nx release` command.

View File

@ -18,7 +18,7 @@ Now that we're working on the CI pipeline, it is important for your changes to b
Now connect your repository to Nx Cloud with the following command: Now connect your repository to Nx Cloud with the following command:
```shell ```shell
nx connect npx nx connect
``` ```
A browser window will open to register your repository in your [Nx Cloud](https://cloud.nx.app) account. The link is also printed to the terminal if the windows does not open, or you closed it before finishing the steps. The app will guide you to create a PR to enable Nx Cloud on your repository. A browser window will open to register your repository in your [Nx Cloud](https://cloud.nx.app) account. The link is also printed to the terminal if the windows does not open, or you closed it before finishing the steps. The app will guide you to create a PR to enable Nx Cloud on your repository.

View File

@ -8,7 +8,7 @@ title: Create a CI Workflow
Use the following command to generate a CI workflow file. Use the following command to generate a CI workflow file.
```shell ```shell
nx generate ci-workflow --ci=github npx nx generate ci-workflow --ci=github
``` ```
This generator creates a `.github/workflows/ci.yml` file that contains a CI pipeline that will run the `lint`, `test`, `build` and `e2e` tasks for projects that are affected by any given PR. If you would like to also distribute tasks across multiple machines to ensure fast and reliable CI runs, uncomment the `nx-cloud start-ci-run` line and have the `nx affected` line run the `e2e-ci` task instead of `e2e`. This generator creates a `.github/workflows/ci.yml` file that contains a CI pipeline that will run the `lint`, `test`, `build` and `e2e` tasks for projects that are affected by any given PR. If you would like to also distribute tasks across multiple machines to ensure fast and reliable CI runs, uncomment the `nx-cloud start-ci-run` line and have the `nx affected` line run the `e2e-ci` task instead of `e2e`.

View File

@ -38,7 +38,7 @@ Then the following command would run the tests for only the projects affected by
```shell ```shell
# This does not work in the browser webcontainer # This does not work in the browser webcontainer
nx affected -t test npx nx affected -t test
``` ```
:::info :::info
@ -48,7 +48,7 @@ This webcontainer does not have `git` enabled, so we have to manually tell Nx wh
Use this command in the webcontainer terminal to manually specify which files have been touched. Use this command in the webcontainer terminal to manually specify which files have been touched.
```shell ```shell
nx affected -t test --files=libs/products/src/lib/products.tsx npx nx affected -t test --files=libs/products/src/lib/products.tsx
``` ```
Note that the unit tests were run for `products`, `react-store` and `inventory`, but not for `orders` because a change to `products` can not possibly break the tests for `orders`. In a small repo like this, there isn't a lot of time saved, but as there are more tests and more projects, this quickly becomes an essential command. Note that the unit tests were run for `products`, `react-store` and `inventory`, but not for `orders` because a change to `products` can not possibly break the tests for `orders`. In a small repo like this, there isn't a lot of time saved, but as there are more tests and more projects, this quickly becomes an essential command.
@ -56,7 +56,7 @@ Note that the unit tests were run for `products`, `react-store` and `inventory`,
You can also see what projects are affected in the graph visualizer with; You can also see what projects are affected in the graph visualizer with;
```shell ```shell
nx graph --affected --files=libs/products/src/lib/products.tsx npx nx graph --affected --files=libs/products/src/lib/products.tsx
``` ```
## Build the Apps for Deployment ## Build the Apps for Deployment
@ -66,7 +66,7 @@ nx graph --affected --files=libs/products/src/lib/products.tsx
If you're ready and want to ship your applications, you can build them using If you're ready and want to ship your applications, you can build them using
```shell ```shell
nx run-many -t build npx nx run-many -t build
``` ```
All the required files will be placed in `/apps/react-store/dist` and `/apps/inventory/dist` and can be deployed to your favorite hosting provider. All the required files will be placed in `/apps/react-store/dist` and `/apps/inventory/dist` and can be deployed to your favorite hosting provider.
@ -117,8 +117,8 @@ Replace the `deploy` script with whatever terminal command you use to deploy you
The `"dependsOn": ["build"]` setting tells Nx to make sure that the project's `build` task has been run successfully before the `deploy` task. The `"dependsOn": ["build"]` setting tells Nx to make sure that the project's `build` task has been run successfully before the `deploy` task.
With the `deploy` tasks defined, you can deploy a single application with `nx deploy react-store` or deploy any applications affected by the current changes with: With the `deploy` tasks defined, you can deploy a single application with `npx nx deploy react-store` or deploy any applications affected by the current changes with:
```shell ```shell
nx affected -t deploy npx nx affected -t deploy
``` ```

View File

@ -77,7 +77,7 @@ To test it, go to your `libs/products/src/lib/products.tsx` file and import the
If you lint your workspace you'll get an error now: If you lint your workspace you'll get an error now:
```shell ```shell
nx run-many -t lint npx nx run-many -t lint
``` ```
``` ```
@ -92,7 +92,7 @@ nx run-many -t lint
> eslint . > eslint .
/home/tutorial/libs/products/src/lib/products.tsx /Users/isaac/Documents/code/nx-recipes/react-monorepo/libs/products/src/lib/products.tsx
3:1 error A project tagged with "scope:products" can only depend on libs tagged with "scope:products", "scope:shared" @nx/enforce-module-boundaries 3:1 error A project tagged with "scope:products" can only depend on libs tagged with "scope:products", "scope:shared" @nx/enforce-module-boundaries
3:10 warning 'Orders' is defined but never used @typescript-eslint/no-unused-vars 3:10 warning 'Orders' is defined but never used @typescript-eslint/no-unused-vars

View File

@ -15,6 +15,7 @@
], ],
"sharedGlobals": [] "sharedGlobals": []
}, },
"nxCloudId": "68101bb54a6391016e75634c",
"plugins": [ "plugins": [
{ {
"plugin": "@nx/js/typescript", "plugin": "@nx/js/typescript",

View File

@ -28,7 +28,7 @@ If you experience technical issues with the in-browser tutorial, try refreshing
Create a new React monorepo with the following command: Create a new React monorepo with the following command:
```shell ```shell
npx create-nx-workspace@latest react-monorepo --preset=react-monorepo --nx-cloud=skip npx create-nx-workspace@latest react-monorepo --preset=react-monorepo
``` ```
``` ```
@ -41,6 +41,7 @@ NX Let's create a new workspace [https://nx.dev/getting-started/intro]
✔ Default stylesheet format · css ✔ Default stylesheet format · css
✔ Would you like to use ESLint? · Yes ✔ Would you like to use ESLint? · Yes
✔ Would you like to use Prettier for code formatting? · Yes ✔ Would you like to use Prettier for code formatting? · Yes
✔ Which CI provider would you like to use? · github
``` ```
Let's name the initial application `react-store`. In this tutorial we're going to use `vite` as a bundler, `cypress` for e2e tests and `css` for styling. We'll talk more about how Nx integrates with GitHub Actions later in the tutorial. The above command generates the following structure: Let's name the initial application `react-store`. In this tutorial we're going to use `vite` as a bundler, `cypress` for e2e tests and `css` for styling. We'll talk more about how Nx integrates with GitHub Actions later in the tutorial. The above command generates the following structure:
@ -77,7 +78,7 @@ Let's name the initial application `react-store`. In this tutorial we're going t
The setup includes.. The setup includes..
- a new React application (`apps/react-store/`) - a new React application (`apps/react-store/`)
- a Cypress based set of e2e tests (`apps/react-store-e2e/`) - a Playwright based set of e2e tests (`apps/react-store-e2e/`)
- Prettier preconfigured - Prettier preconfigured
- ESLint preconfigured - ESLint preconfigured
- Jest preconfigured - Jest preconfigured

View File

@ -14,7 +14,7 @@ previews:
To serve your new React application, just run: To serve your new React application, just run:
```shell ```shell
nx serve react-store npx nx serve react-store
``` ```
Your application should be served at [http://localhost:4200](http://localhost:4200). Your application should be served at [http://localhost:4200](http://localhost:4200).

View File

@ -22,7 +22,7 @@ export default defineConfig({
// plugins: [ nxViteTsPaths() ], // plugins: [ nxViteTsPaths() ],
// }, // },
build: { build: {
outDir: './build', outDir: './build/react-store',
emptyOutDir: true, emptyOutDir: true,
reportCompressedSize: true, reportCompressedSize: true,
commonjsOptions: { commonjsOptions: {

View File

@ -5,7 +5,7 @@ previews:
- { - {
port: 4211, port: 4211,
title: 'Project Details View', title: 'Project Details View',
pathname: '/project-details/react-store', pathname: '/project-details/%40react-monorepo%2Freact-store',
} }
--- ---
@ -18,7 +18,7 @@ previews:
Nx identifies available tasks for your project from [tooling configuration files](/concepts/inferred-tasks), `package.json` scripts and the targets defined in `project.json`. To view the tasks that Nx has detected, look in the [Nx Console](/getting-started/editor-setup) project detail view or run: Nx identifies available tasks for your project from [tooling configuration files](/concepts/inferred-tasks), `package.json` scripts and the targets defined in `project.json`. To view the tasks that Nx has detected, look in the [Nx Console](/getting-started/editor-setup) project detail view or run:
```shell ```shell
nx show project react-store npx nx show project @react-monorepo/react-store
``` ```
If you expand the `build` task, you can see that it was created by the `@nx/vite` plugin by analyzing your `vite.config.ts` file. Notice the outputs are defined as `{projectRoot}/dist`. This value is being read from the `build.outDir` defined in your `vite.config.ts` file. Let's change that value in your `vite.config.ts` file: If you expand the `build` task, you can see that it was created by the `@nx/vite` plugin by analyzing your `vite.config.ts` file. Notice the outputs are defined as `{projectRoot}/dist`. This value is being read from the `build.outDir` defined in your `vite.config.ts` file. Let's change that value in your `vite.config.ts` file:

View File

@ -12,7 +12,7 @@ title: Add an Application
Nx plugins usually provide [generators](/features/generate-code) that allow you to easily scaffold code, configuration or entire projects. To see what capabilities the `@nx/react` plugin provides, run the following command and inspect the output: Nx plugins usually provide [generators](/features/generate-code) that allow you to easily scaffold code, configuration or entire projects. To see what capabilities the `@nx/react` plugin provides, run the following command and inspect the output:
```shell ```shell
nx list @nx/react npx nx list @nx/react
``` ```
:::info :::info
@ -27,7 +27,7 @@ More info can be found in [the integrate with editors article](/getting-started/
Run the following command to generate a new `inventory` application. Note how we append `--dry-run` to first check the output. Run the following command to generate a new `inventory` application. Note how we append `--dry-run` to first check the output.
```shell ```shell
nx g @nx/react:app apps/inventory --dry-run npx nx g @nx/react:app apps/inventory --dry-run
``` ```
``` ```
@ -35,11 +35,11 @@ NX Generating @nx/react:application
✔ Would you like to add React Router to this application? (y/N) · false ✔ Would you like to add React Router to this application? (y/N) · false
✔ What unit test runner should be used? · vitest ✔ What unit test runner should be used? · vitest
✔ Which E2E test runner would you like to use? · none ✔ Which E2E test runner would you like to use? · cypress
``` ```
As you can see, it generates a new application in the `apps/inventory/` folder. Let's actually run the generator by removing the `--dry-run` flag. As you can see, it generates a new application in the `apps/inventory/` folder. Let's actually run the generator by removing the `--dry-run` flag.
```shell ```shell
nx g @nx/react:app apps/inventory npx nx g @nx/react:app apps/inventory
``` ```

View File

@ -15,6 +15,7 @@
], ],
"sharedGlobals": [] "sharedGlobals": []
}, },
"nxCloudId": "68101bb54a6391016e75634c",
"plugins": [ "plugins": [
{ {
"plugin": "@nx/js/typescript", "plugin": "@nx/js/typescript",

View File

@ -53,15 +53,9 @@ Nx allows you to separate this logic into "local libraries". The main benefits i
Let's assume our domain areas include `products`, `orders` and some more generic design system components, called `ui`. We can generate a new library for each of these areas using the React library generator: Let's assume our domain areas include `products`, `orders` and some more generic design system components, called `ui`. We can generate a new library for each of these areas using the React library generator:
```shell ```shell
nx g @nx/react:library libs/products --unitTestRunner=vitest --bundler=none npx nx g @nx/react:library libs/products --unitTestRunner=vitest --bundler=none
``` npx nx g @nx/react:library libs/orders --unitTestRunner=vitest --bundler=none
npx nx g @nx/react:library libs/shared/ui --unitTestRunner=vitest --bundler=none
```shell
nx g @nx/react:library libs/orders --unitTestRunner=vitest --bundler=none
```
```shell
nx g @nx/react:library libs/shared/ui --unitTestRunner=vitest --bundler=none
``` ```
Note how we type out the full path in the `directory` flag to place the libraries into a subfolder. You can choose whatever folder structure you like to organize your projects. If you change your mind later, you can run the [move generator](/nx-api/workspace/generators/move) to move a project to a different folder. Note how we type out the full path in the `directory` flag to place the libraries into a subfolder. You can choose whatever folder structure you like to organize your projects. If you change your mind later, you can run the [move generator](/nx-api/workspace/generators/move) to move a project to a different folder.
@ -105,7 +99,7 @@ Running the above commands should lead to the following directory structure:
Each of these libraries Each of these libraries
- has a project details view where you can see the available tasks (e.g. running tests for just orders: `nx test orders`) - has a project details view where you can see the available tasks (e.g. running tests for just orders: `npx nx test orders`)
- has its own `package.json` file where you can customize targets - has its own `package.json` file where you can customize targets
- has the name you specified in the generate command; you can find the name in the corresponding `package.json` file - has the name you specified in the generate command; you can find the name in the corresponding `package.json` file
- has a dedicated `index.ts` file which is the "public API" of the library - has a dedicated `index.ts` file which is the "public API" of the library

View File

@ -1,17 +0,0 @@
import { render } from '@testing-library/react';
import App from './app';
describe('App', () => {
it('should render successfully', () => {
const { baseElement } = render(<App />);
expect(baseElement).toBeTruthy();
});
it('should have a greeting as the title', () => {
const { getByText } = render(<App />);
expect(
getByText(new RegExp('Products', 'gi'))
).toBeTruthy();
});
});

View File

@ -1,17 +0,0 @@
import { render } from '@testing-library/react';
import App from './app';
describe('App', () => {
it('should render successfully', () => {
const { baseElement } = render(<App />);
expect(baseElement).toBeTruthy();
});
it('should have a greeting as the title', () => {
const { getByText } = render(<App />);
expect(
getByText(new RegExp('Home', 'gi'))
).toBeTruthy();
});
});

View File

@ -2,7 +2,7 @@
type: lesson type: lesson
title: Share Code title: Share Code
previews: previews:
- { port: 4200, title: 'ReactStore', pathname: '/products' } - { port: 4211, title: 'Project Graph', pathname: '/projects' }
--- ---
### Import Libraries into the React Applications ### Import Libraries into the React Applications
@ -13,7 +13,7 @@ previews:
All libraries that we generate are automatically included in the `workspaces` defined in the root-level `package.json`. All libraries that we generate are automatically included in the `workspaces` defined in the root-level `package.json`.
```file:/package.json title="/package.json" collapse={3-53} no-apply ```file:/package.json title="/package.json" collapse={3-51}
``` ```
@ -61,11 +61,7 @@ export function App() {
export default App; export default App;
``` ```
Serving your app (`nx serve react-store`) and then navigating to `/products` should give you the following result: Serving your app (`npx nx serve react-store`) and then navigating to `/products` should give you the following result:
```shell
nx serve react-store
```
![products route](/documentation/shared/tutorials/react-tutorial-products-route.png) ![products route](/documentation/shared/tutorials/react-tutorial-products-route.png)

Some files were not shown because too many files have changed in this diff Show More