docs(core): add Nx to existing projects
This commit is contained in:
parent
939c598dfc
commit
a7408d0a1e
@ -752,16 +752,16 @@
|
|||||||
"id": "adopting-nx",
|
"id": "adopting-nx",
|
||||||
"description": "Adopting Nx incrementally, on existing project or from scratch.",
|
"description": "Adopting Nx incrementally, on existing project or from scratch.",
|
||||||
"itemList": [
|
"itemList": [
|
||||||
{
|
|
||||||
"name": "Nx and Lerna",
|
|
||||||
"id": "lerna-and-nx",
|
|
||||||
"file": "shared/migration/lerna-and-nx"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "NPM/Yarn/PNPM workspaces",
|
"name": "NPM/Yarn/PNPM workspaces",
|
||||||
"id": "adding-to-monorepo",
|
"id": "adding-to-monorepo",
|
||||||
"file": "shared/migration/adding-to-monorepo"
|
"file": "shared/migration/adding-to-monorepo"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Add to any Project",
|
||||||
|
"id": "adding-to-existing-project",
|
||||||
|
"file": "shared/migration/adding-to-existing-project"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "From CRA",
|
"name": "From CRA",
|
||||||
"id": "migration-cra",
|
"id": "migration-cra",
|
||||||
@ -772,6 +772,11 @@
|
|||||||
"id": "migration-angular",
|
"id": "migration-angular",
|
||||||
"file": "shared/migration/migration-angular"
|
"file": "shared/migration/migration-angular"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Nx and Lerna",
|
||||||
|
"id": "lerna-and-nx",
|
||||||
|
"file": "shared/migration/lerna-and-nx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "From AngularJS",
|
"name": "From AngularJS",
|
||||||
"id": "migration-angularjs",
|
"id": "migration-angularjs",
|
||||||
|
|||||||
130
docs/shared/migration/adding-to-existing-project.md
Normal file
130
docs/shared/migration/adding-to-existing-project.md
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
# Adding Nx to your Existing Project
|
||||||
|
|
||||||
|
Nx can be added to any type of project, not just monorepos. The main benefit is to get caching abilties for the package scripts. Each project usually has a set of scripts in the `package.json`:
|
||||||
|
|
||||||
|
```json {% fileName="package.json" %}
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc -p tsconfig.json",
|
||||||
|
"test": "jest",
|
||||||
|
"lint": "eslint . --ext .ts",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can make these scripts faster by leveraging Nx's caching capabilities. For example:
|
||||||
|
|
||||||
|
- You change some spec files: in that case the `build` task can be cached and doesn't have to re-run.
|
||||||
|
- You update your docs, changing a couple of markdown files: then there's no need to re-run builds, tests, linting on your CI. All you might want to do is trigger the Docusaurus build.
|
||||||
|
|
||||||
|
## Installing Nx on a Non-Monorepo Project
|
||||||
|
|
||||||
|
Run the following command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npx nx@latest init
|
||||||
|
```
|
||||||
|
|
||||||
|
This will
|
||||||
|
|
||||||
|
- collect all the NPM scripts in the corresponding `package.json` files of your workspace packages
|
||||||
|
- ask you which of those scripts are cacheable (e.g. build, test, lint)
|
||||||
|
- ask you which of those scripts might need to be run in a certain order (e.g. if you run the `build` script you might want to first build all the dependent projects)
|
||||||
|
- ask you for custom output folders that should be captured as part of the caching
|
||||||
|
|
||||||
|
This process adds `nx` to your `package.json` at the root of your workspace:
|
||||||
|
|
||||||
|
```json {% fileName="package.json" %}
|
||||||
|
{
|
||||||
|
"name": "my-workspace",
|
||||||
|
...
|
||||||
|
"devDependencies": {
|
||||||
|
...
|
||||||
|
"nx": "15.3.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition it generates a `nx.json` based on your answers during the setup process. This includes cacheable operations as well as some initial definition of the task pipeline. Here is an example:
|
||||||
|
|
||||||
|
```json {% fileName="nx.json" %}
|
||||||
|
{
|
||||||
|
"tasksRunnerOptions": {
|
||||||
|
"default": {
|
||||||
|
"runner": "nx/tasks-runners/default",
|
||||||
|
"options": {
|
||||||
|
"cacheableOperations": ["build", "lint"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wrapping Cacheable Scripts
|
||||||
|
|
||||||
|
Nx also automatically wraps your cacheable scripts with the `nx exec` command. The main advantage here is that you can still keep using `npm start` or `npm run build` (or other package manager's alternatives) as you're accustomed to. But still get the benefits of making those operations cacheble.
|
||||||
|
|
||||||
|
Here's an example of a `build` and `lint` script being wrapped by Nx:
|
||||||
|
|
||||||
|
```json {% fileName="package.json" %}
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"scripts": {
|
||||||
|
"build": "nx exec -- vite build",
|
||||||
|
"lint": "nx exec -- eslint \"src/**/*.ts*\"",
|
||||||
|
...
|
||||||
|
"dev": "vite",
|
||||||
|
"start": "vite --open",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
...
|
||||||
|
"nx": "15.3.0"
|
||||||
|
},
|
||||||
|
"nx": {
|
||||||
|
"includeScripts": [
|
||||||
|
"build",
|
||||||
|
"lint"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{% callout type="note" title="Use Nx commands directly" %}
|
||||||
|
|
||||||
|
Alternatively you could obviously also just switch to using `nx` for invoking the commands. Like `nx build` rather than `npm run build`.
|
||||||
|
|
||||||
|
{% /callout %}
|
||||||
|
|
||||||
|
## Fine-tuning caching with Nx Inputs
|
||||||
|
|
||||||
|
To get the best caching results, you can customize which inputs should be accounted for when it comes to caching certain commands. This can be done in your `nx.json`.
|
||||||
|
|
||||||
|
For example, excluding markdown files from the `lint` task cache:
|
||||||
|
|
||||||
|
```json {% fileName="nx.json" %}
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"targetDefaults": {
|
||||||
|
"lint": {
|
||||||
|
"inputs": ["{projectRoot}/**/*.ts","!**/*.md"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This includes all TypeScript files, but excludes markdown files. As a result, changing your README won't invalidate your "lint cache".
|
||||||
|
|
||||||
|
Learn more about [Nx Inputs](/more-concepts/customizing-inputs).
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
{% cards %}
|
||||||
|
|
||||||
|
{% card title="Customizing Inputs and Named Inputs" description="Learn more about how to fine-tune caching with custom inputs" type="documentation" url="/more-concepts/customizing-inputs" /%}
|
||||||
|
|
||||||
|
{% card title="Cache Task Results" description="Learn more about how caching works" type="documentation" url="/core-features/cache-task-results" /%}
|
||||||
|
|
||||||
|
{% card title="Adding Nx to NPM/Yarn/PNPM Workspace" description="Learn more about how to add Nx to an existing monorepo" type="documentation" url="/recipes/adopting-nx/adding-to-monorepo" /%}
|
||||||
|
|
||||||
|
{% /cards %}
|
||||||
@ -1,160 +1,99 @@
|
|||||||
# Adding Nx to Lerna/Yarn/PNPM/NPM Workspace
|
# Adding Nx to NPM/Yarn/PNPM Workspace
|
||||||
|
|
||||||
{% callout type="note" title="Migrating from Lerna?" %}
|
{% callout type="note" title="Migrating from Lerna?" %}
|
||||||
Interested in migrating from [Lerna](https://github.com/lerna/lerna) in particular? In case you missed it, Nrwl, the company behind Nx, [took over stewardship of Lerna](https://blog.nrwl.io/lerna-is-dead-long-live-lerna-61259f97dbd9). This allows for a much better integration between the two. [Read more in our dedicated guide](/recipes/adopting-nx/lerna-and-nx).
|
Interested in migrating from [Lerna](https://github.com/lerna/lerna) in particular? In case you missed it, Lerna v6 is powering Nx underneath. As a result, Lerna gets all the modern features such as caching and task pipelines. Read more on [https://lerna.js.org/upgrade](https://lerna.js.org/upgrade).
|
||||||
{% /callout %}
|
{% /callout %}
|
||||||
|
|
||||||
**Short story:** you can use Nx easily together with your current Lerna/Yarn/PNPM/NPM monorepo setup. Why? To speed up
|
Nx has first class support for [package-based monorepos](/getting-started/package-based-repo-tutorial). As a result, if you have an existing NPM/Yarn or PNPM based monorepo setup, you can easily add Nx to get
|
||||||
your tasks by leveraging Nx's powerful scheduling and caching capabilities.
|
|
||||||
|
|
||||||
Adding Nx is a low impact operation that does not require any particular change to your repository like how your
|
- fast [task scheduling](/core-features/run-tasks)
|
||||||
packages and scripts are organized. Whatever setup you have still works the same way but faster and with better dev
|
- support for [task pipelines](/concepts/task-pipeline-configuration)
|
||||||
ergonomics. You could manually configure Nx, but it is way easier by running the following command:
|
- [caching](/core-features/cache-task-results)
|
||||||
|
- optionally [remote caching with Nx Cloud](/core-features/share-your-cache)
|
||||||
|
- optionally [distributed task execution with Nx Cloud](/core-features/distribute-task-execution)
|
||||||
|
|
||||||
|
This is a low-impact operation because all that needs to be done is to install the `nx` package at the root-level and add an `nx.json` for configuring caching and task pipelines.
|
||||||
|
|
||||||
|
## Installing Nx
|
||||||
|
|
||||||
|
Run the following command to automatically set up Nx:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
npx add-nx-to-monorepo
|
npx nx@latest init
|
||||||
```
|
```
|
||||||
|
|
||||||
Here's a short video walking you through the steps of adding Nx to a Lerna & Yarn workspaces based monorepo:
|
Running this command will
|
||||||
|
|
||||||
{% youtube
|
- collect all the NPM scripts in the corresponding `package.json` files of your workspace packages
|
||||||
src="https://www.youtube.com/embed/hCm373Aq1uQ"
|
- ask you which of those scripts are cacheable (e.g. build, test, lint)
|
||||||
title="Add Nx to a Lerna & Yarn workspaces monorepo"
|
- ask you which of those scripts might need to be run in a certain order (e.g. if you run the `build` script you might want to first build all the dependent projects)
|
||||||
width="100%" /%}
|
- ask you for custom output folders that should be captured as part of the caching
|
||||||
|
|
||||||
`npx add-nx-to-monorepo` does the following:
|
This process adds `nx` to your `package.json` at the root of your workspace:
|
||||||
|
|
||||||
1. Add Nx to your package.json.
|
|
||||||
2. Create `nx.json`, containing all the necessary configuration for Nx.
|
|
||||||
3. Set up [Nx Cloud](https://nx.app) (if you chose "yes").
|
|
||||||
|
|
||||||
{% callout type="note" title="Familiar with Turborepo?" %}
|
|
||||||
If you are familiar with Turborepo, check out [this guide](/more-concepts/turbo-and-nx). At this point, Nx can do anything Turbo can, and much more.
|
|
||||||
{% /callout %}
|
|
||||||
|
|
||||||
## What You Get Right Away
|
|
||||||
|
|
||||||
This sets up Nx core in your existing monorepo which comes with a series of interesting features that help intelligenty schedule tasks and make sure operations are quick:
|
|
||||||
|
|
||||||
- **Run any npm script -** with Nx installed, you can use its powerful task scheduler which automatically picks up your
|
|
||||||
npm scripts from your package's script section. For instance if package `myproj` has a `build` script, you can just
|
|
||||||
run it using `nx build myproj`. Similarly, for running tests use `nx test myproj` and so on.
|
|
||||||
- **Parallelization and task dependencies -** Nx
|
|
||||||
automatically [knows how your projects relate to each other](/more-concepts/how-project-graph-is-built). As a result, if `project-a`
|
|
||||||
depends on `project-b` and you run `nx build project-a`, Nx first runs the builds for all of `project-a`'s
|
|
||||||
dependencies, in this specific example it builds `project-b` before `project-a`.
|
|
||||||
- **Only run what changed -** Using [Nx affected commands](/concepts/affected) you only really execute tasks on the
|
|
||||||
projects that changed, compared to a given baseline (usually the main branch).
|
|
||||||
- **Caching -** You get Nx's [computation caching](/concepts/how-caching-works) for free. All operations, including artifacts and
|
|
||||||
terminal output are restored from the cache (if present) in a completely transparent way without disrupting your DX.
|
|
||||||
No configuration needed. Obviously this results in an incredible speed improvement.
|
|
||||||
- **Distributed Task Execution -** This is unique to Nx. In combination with Nx Cloud your tasks are automatically
|
|
||||||
distributed across CI agents, taking into account build order, maximizing parallelization and thus agent utilization.
|
|
||||||
It even learns from previous runs to better distribute tasks! [Learn more](/concepts/dte)
|
|
||||||
- **Interactive workspace visualization -** Nx comes with a [project graph visualization](/core-features/explore-graph)
|
|
||||||
built-in which you can use to interactively explore your workspace, understand dependencies and find paths between
|
|
||||||
nodes and why they exist.
|
|
||||||
- **Dedicated VSCode extension -** You can install [Nx Console](/core-features/integrate-with-editors) which is a dedicated VSCode extension
|
|
||||||
to provide a visual interface for navigating your monorepo workspace in terms of launching commands as well as for
|
|
||||||
generating code.
|
|
||||||
- **GitHub integration -** Install the [Nx Cloud Github App](https://github.com/apps/nx-cloud) to get inline reporting
|
|
||||||
on your CI jobs.
|
|
||||||
|
|
||||||
## Looking for integrating Lerna and Nx?
|
|
||||||
|
|
||||||
Check out our dedicated guide: [Lerna and Nx](/recipes/adopting-nx/lerna-and-nx)
|
|
||||||
|
|
||||||
## Further customizations
|
|
||||||
|
|
||||||
Here are some further customizations we found to be useful when adding Nx to existing monorepos.
|
|
||||||
|
|
||||||
### Excluding Sources
|
|
||||||
|
|
||||||
The `add-nx-to-monorepo` command does its best to figure out what projects you have in the repo. Similar to other tools,
|
|
||||||
it looks at the `workspaces` property in the root `package.json` and tries to find all `package.json` files matching the
|
|
||||||
globs. You can change those globs to exclude some projects. You can also exclude files by creating an `.nxignore` file,
|
|
||||||
like this:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party # nx will ignore everything in the third-party dir
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enabling JS Analysis
|
|
||||||
|
|
||||||
After running `add-nx-to-monorepo` Nx will only analyze `package.json` files in the same way Lerna or Turborepo do.
|
|
||||||
|
|
||||||
```json {% fileName="package.json" %}
|
```json {% fileName="package.json" %}
|
||||||
{
|
{
|
||||||
"pluginsConfig": {
|
"name": "my-workspace",
|
||||||
"@nrwl/js": {
|
...
|
||||||
"analyzeSourceFiles": false
|
"devDependencies": {
|
||||||
}
|
...
|
||||||
|
"nx": "15.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
We do this because most existing Lerna monorepos have implicit dependencies between projects Lerna knows nothing about.
|
It also creates a `nx.json` based on the answers given during the setup process. This includes cacheable operations as well as some initial definition of the task pipeline. Here is an example:
|
||||||
|
|
||||||
To enable JS analysis, add the following to your configuration:
|
```json {% fileName="nx.json" %}
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
{
|
||||||
"pluginsConfig": {
|
"tasksRunnerOptions": {
|
||||||
"@nrwl/js": {
|
"default": {
|
||||||
"analyzeSourceFiles": true
|
"runner": "nx/tasks-runners/default",
|
||||||
|
"options": {
|
||||||
|
"cacheableOperations": ["build", "test", "lint"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"targetDefaults": {
|
||||||
|
"build": {
|
||||||
|
"dependsOn": ["^build"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In this case, Nx will consider all import
|
## Incrementally Adopting Nx
|
||||||
and require statements in your JS/TS files when creating its project graph. If you do that, you can also add the `paths`
|
|
||||||
property to the root `tsconfig.base.json` (if you don't have this file, create it), which will tell Nx how to resolve
|
|
||||||
imports.
|
|
||||||
|
|
||||||
```json {% fileName="tsconfig.base.json" %}
|
In a package-based monorepo, Nx only manages the scheduling and caching of your npm scripts. Hence, it can easily be adopt incrementally by initially using Nx just for a subset of your scripts and then gradually adding more.
|
||||||
{
|
|
||||||
"compilerOptions": {
|
For example, use Nx to run your builds:
|
||||||
"paths": {
|
|
||||||
"one": ["packages/one/index"],
|
```shell
|
||||||
"one/*": ["packages/one/*"],
|
npx nx run-many --target=build
|
||||||
"two": ["packages/two/index"],
|
|
||||||
"two/*": ["packages/two/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Next Steps
|
But instead keep using NPM/Yarn/PNPM workspace commands for your tests and other scripts. Here's an example of using PNPM commands to run tests across packages
|
||||||
|
|
||||||
Nx is like a VS Code of build tools. It has a very powerful core, but it's really the plugins and extra capabilities
|
```shell
|
||||||
that really transform how you develop.
|
pnpm run -r test
|
||||||
|
```
|
||||||
|
|
||||||
Nx has first class support for React, Next.js, React Native, Angular, Node, NestJS, Jest, Cypress, Storybook and many
|
This allows for incrementally adopting Nx in your existing workspace.
|
||||||
more. All the plugins are designed to work together and create a cohesive and pleasant to use dev environment.
|
|
||||||
|
|
||||||
In addition, Nx makes a lot of things much easier, like building large apps incrementally, distributing CI (no point in
|
## Learn More
|
||||||
doing caching unless you can do that), enforcing best practices, building design systems.
|
|
||||||
|
|
||||||
## Real world examples of using add-nx-to-monorepo
|
{% cards %}
|
||||||
|
|
||||||
### Speeding Up Facebook React Monorepo with Nx
|
{% card title="Cache Task Results" description="Learn more about how caching works" type="documentation" url="/core-features/cache-task-results" /%}
|
||||||
|
|
||||||
{% youtube
|
{% card title="Task Pipeline Configuration" description="Learn more about how to setup task dependencies" type="documentation" url="/concepts/task-pipeline-configuration" /%}
|
||||||
src="https://www.youtube.com/embed/XLP2RAOwfLQ"
|
|
||||||
title="Speeding Up github.com/facebook/react with Nx"
|
|
||||||
width="100%" /%}
|
|
||||||
|
|
||||||
### Speeding Up Remotion Monorepo with Nx
|
{% card title="Nx Ignore" description="Learn about how to ignore certain projects using .nxignore" type="documentation" url="/reference/nxignore" /%}
|
||||||
|
|
||||||
{% youtube
|
{% card title="Nx and Turbo" description="Read about how Nx compares to Turborepo" url="/more-concepts/turbo-and-nx" /%}
|
||||||
src="https://www.youtube.com/embed/TXySu4dZLp0"
|
|
||||||
title="Speeding Up Remotion Monorepo with Nx"
|
|
||||||
width="100%" /%}
|
|
||||||
|
|
||||||
### Speeding Up Storybook Monorepo with Nx
|
{% card title="Nx and Lerna" description="Read about how Nx and Lerna can be used together" url="/recipes/adopting-nx/lerna-and-nx" /%}
|
||||||
|
|
||||||
{% youtube
|
{% card title="Integrated Repos vs Package-Based Repos" description="Learn about two styles of monorepos." url="/concepts/integrated-vs-package-based" /%}
|
||||||
src="https://www.youtube.com/embed/3o8w6jbDr4A"
|
|
||||||
title="Speeding Up Storybook Monorepo with Nx"
|
{% /cards %}
|
||||||
width="100%" /%}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user