In VCS, a monorepo is:
- A software-development strategy.
- Where the code for a number of projects is stored in the same repository.
- A powerful open-source build system.
- Provides tools and techniques for:
- Enhancing developer productivity.
- Optimizing CI performance.
- Maintaining code quality.
- Run tasks in parallel based on the dependencies between them.
- Caches tasks.
- Works the same way with any JS or non-JS project.
- Workspace is a monorepo in which we are gonna have our codebase.
npx create-nx-workspace --pm pnpm
- Will ask you a bunch of question about what kind of workspace do you need.
- A set of utilities for building Nx plugins.
-
Run multiple tasks:
npx nx --run-many targetName1 targetName2
-
Each task has what we call it "executor".
-
Nx picks up tasks from:
package.json
scripts.- Defined inside
project.json
/nx.json
.
And their config:
- It infer/deduce them from configuration files (e.g.
jest.config.ts
).
-
Run tasks affected by your PR:
npx nx affected -t test
.
-
targetDefaults - Here we assume Same Target Name, Same Executor.
-
Multiple targets (tasks like
build
,test
) with the same name across different projects, they all use the same executor.
What did we get out of this?
- DRY principle.
- Ease of maintenance and development.
- Easer time to reason about each project's configuration.
Folder structure Before operation libs/lib1/project.json
nx.json
After operation libs/lib1/project.json
you-say/.github/docs/monorepo/libs-lib1-project.json
Lines 1 to 40 in 182d760
you-say/.github/docs/monorepo/root-nx-for-libs.json
Lines 1 to 35 in 182d760
you-say/.github/docs/monorepo/reduced-project.json
Lines 1 to 16 in 91a2759
-
Two
build
targets with different executors:Do NOT use
build
as key inside thetargetDefaults
. But instead use use executor name as key:nx.json
project.json
you-say/.github/docs/monorepo/executor-as-key.js
Lines 15 to 33 in 0324448
you-say/.github/docs/monorepo/executor-as-key.js
Lines 2 to 12 in 0324448
-
If you have to make exceptions for most of the projects in your repository, then that setting probably should not be a default.
Important
Learn more about project.json
here.
-
Battle-tested computation caching system.
-
Code is never rebuilt twice.
-
Can be don in either:
libs/lib1/project.json
nx.json
you-say/.github/docs/monorepo/cache.js
Lines 2 to 8 in aea61a6
you-say/.github/docs/monorepo/cache.js
Lines 11 to 17 in aea61a6
-
The operation that you wanna cache need to be pure, no side effect is allowed. E.g. you cannot cache your e2e tests since something might have changed on your backend.
-
inputs
: defines what gets included as part of the calculated hash (e.g. files, environment variables, etc.).Exclude all
*.md
files from the cache so that whenever we change the any markdown file, it does not invalidate the build cache.libs/lib1/project.json
nx.json
you-say/.github/docs/monorepo/cache.js
Lines 9 to 16 in 5a15e2b
you-say/.github/docs/monorepo/cache.js
Lines 26 to 33 in 5a15e2b
-
outputs
: defines where the result of a task is placed after task execution (e.g. where is our coverage report).Define output locations if they differ from the usual
dist
orbuild
directory since Nx by default recognizes those.
Note
Learn about what are projectName
, and they other place holders in glossary.
- Make sure to install the
@nx/whatever
version that matches the version ofnx
in your repository. If the version numbers get out of sync, you can encounter some difficult to debug errors. You can fix Nx version mismatches with this recipe. - Nx plugins lift the burden of things like scaffolding a new app (e.g. NestJS, NextJS), testing, building, etc
- You can use
nx graph
andnx show projects
to see what is going on in your monorepo.
This command is NOT gonna upgrade your devDeps and deps to the latest version. It is only upgrading nx
and its belongings. So we can use other approaches to upgrade our dependencies:
npm outdated
npm update
But most of the times npm update
will NOT do the trick. So in those cases we need to rely on tools such as npm-check-updates
npm install -g npm-check-updates
ncu
if do not need migrations.json
(scenarios such as applying same migration in other branches) remove it.