diff --git a/docs/map.json b/docs/map.json index 4c14100a4c..5f0f18db64 100644 --- a/docs/map.json +++ b/docs/map.json @@ -752,16 +752,16 @@ "id": "adopting-nx", "description": "Adopting Nx incrementally, on existing project or from scratch.", "itemList": [ - { - "name": "Nx and Lerna", - "id": "lerna-and-nx", - "file": "shared/migration/lerna-and-nx" - }, { "name": "NPM/Yarn/PNPM workspaces", "id": "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", "id": "migration-cra", @@ -772,6 +772,11 @@ "id": "migration-angular", "file": "shared/migration/migration-angular" }, + { + "name": "Nx and Lerna", + "id": "lerna-and-nx", + "file": "shared/migration/lerna-and-nx" + }, { "name": "From AngularJS", "id": "migration-angularjs", diff --git a/docs/shared/migration/adding-to-existing-project.md b/docs/shared/migration/adding-to-existing-project.md new file mode 100644 index 0000000000..bf0f10170b --- /dev/null +++ b/docs/shared/migration/adding-to-existing-project.md @@ -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 %} diff --git a/docs/shared/migration/adding-to-monorepo.md b/docs/shared/migration/adding-to-monorepo.md index eccb344a60..267dffe5eb 100644 --- a/docs/shared/migration/adding-to-monorepo.md +++ b/docs/shared/migration/adding-to-monorepo.md @@ -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?" %} -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 %} -**Short story:** you can use Nx easily together with your current Lerna/Yarn/PNPM/NPM monorepo setup. Why? To speed up -your tasks by leveraging Nx's powerful scheduling and caching capabilities. +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 -Adding Nx is a low impact operation that does not require any particular change to your repository like how your -packages and scripts are organized. Whatever setup you have still works the same way but faster and with better dev -ergonomics. You could manually configure Nx, but it is way easier by running the following command: +- fast [task scheduling](/core-features/run-tasks) +- support for [task pipelines](/concepts/task-pipeline-configuration) +- [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 -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 -src="https://www.youtube.com/embed/hCm373Aq1uQ" -title="Add Nx to a Lerna & Yarn workspaces monorepo" -width="100%" /%} +- 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 -`npx add-nx-to-monorepo` does the following: - -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. +This process adds `nx` to your `package.json` at the root of your workspace: ```json {% fileName="package.json" %} { - "pluginsConfig": { - "@nrwl/js": { - "analyzeSourceFiles": false - } + "name": "my-workspace", + ... + "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 +```json {% fileName="nx.json" %} { - "pluginsConfig": { - "@nrwl/js": { - "analyzeSourceFiles": true + "tasksRunnerOptions": { + "default": { + "runner": "nx/tasks-runners/default", + "options": { + "cacheableOperations": ["build", "test", "lint"] + } + } + }, + "targetDefaults": { + "build": { + "dependsOn": ["^build"] } } } ``` -In this case, Nx will consider all import -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. +## Incrementally Adopting Nx -```json {% fileName="tsconfig.base.json" %} -{ - "compilerOptions": { - "paths": { - "one": ["packages/one/index"], - "one/*": ["packages/one/*"], - "two": ["packages/two/index"], - "two/*": ["packages/two/*"] - } - } -} +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. + +For example, use Nx to run your builds: + +```shell +npx nx run-many --target=build ``` -## 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 -that really transform how you develop. +```shell +pnpm run -r test +``` -Nx has first class support for React, Next.js, React Native, Angular, Node, NestJS, Jest, Cypress, Storybook and many -more. All the plugins are designed to work together and create a cohesive and pleasant to use dev environment. +This allows for incrementally adopting Nx in your existing workspace. -In addition, Nx makes a lot of things much easier, like building large apps incrementally, distributing CI (no point in -doing caching unless you can do that), enforcing best practices, building design systems. +## Learn More -## 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 -src="https://www.youtube.com/embed/XLP2RAOwfLQ" -title="Speeding Up github.com/facebook/react with Nx" -width="100%" /%} +{% card title="Task Pipeline Configuration" description="Learn more about how to setup task dependencies" type="documentation" url="/concepts/task-pipeline-configuration" /%} -### 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 -src="https://www.youtube.com/embed/TXySu4dZLp0" -title="Speeding Up Remotion Monorepo with Nx" -width="100%" /%} +{% card title="Nx and Turbo" description="Read about how Nx compares to Turborepo" url="/more-concepts/turbo-and-nx" /%} -### 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 -src="https://www.youtube.com/embed/3o8w6jbDr4A" -title="Speeding Up Storybook Monorepo with Nx" -width="100%" /%} +{% card title="Integrated Repos vs Package-Based Repos" description="Learn about two styles of monorepos." url="/concepts/integrated-vs-package-based" /%} + +{% /cards %}