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 abilities for the package scripts. Each project usually has a set of scripts in the package.json
:
1{
2 ...
3 "scripts": {
4 "build": "next build",
5 "lint": "eslint ./src",
6 "test": "node ./run-tests.js"
7 }
8}
9
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.
Install Nx on a Non-Monorepo Project
Run the following command:
❯
npx nx@latest init
This will set up Nx for you - updating the package.json
file and creating a new nx.json
file with Nx configuration based on your answers during the set up process. The set up process will suggest installing Nx plugins that might be useful based on your existing repository. The example below is using the @nx/eslint
and @nx/next
plugins to run ESLint and Next.js tasks with Nx:
1{
2 "plugins": [
3 {
4 "plugin": "@nx/eslint/plugin",
5 "options": {
6 "targetName": "lint"
7 }
8 },
9 {
10 "plugin": "@nx/next/plugin",
11 "options": {
12 "buildTargetName": "build",
13 "devTargetName": "dev",
14 "startTargetName": "start"
15 }
16 }
17 ]
18}
19
When Nx updates your package.json
scripts, it looks for scripts that can be replaced with an Nx command that has caching automatically enabled. The package.json
defined above would be updated to look like this:
1{
2 "name": "my-workspace",
3 ...
4 "scripts": {
5 "build": "nx build",
6 "lint": "nx lint",
7 "test": "node ./run-tests.js"
8 },
9 ...
10 "nx": {
11 "includedScripts": []
12 }
13}
14
The @nx/next
plugin can run next build
for you and set up caching correctly, so it replaces next build
with nx build
. Similarly, @nx/eslint
can set up caching for eslint ./src
. When you run npm run build
or npm run lint
multiple times, you'll see that caching is enabled. You can also call Nx directly from the terminal with nx build
or nx lint
.
The test
script was not recognized by any Nx plugin, so it was left as is.
The includedScripts
array allows you to specify package.json
scripts that can be run with the nx build
syntax.
Inferred Tasks
You may have noticed that @nx/next
provides dev
and start
tasks in addition to the build
task. Those tasks were created by the @nx/next
plugin from your existing Next.js configuration. To view all available tasks, open the Project Details view with Nx Console or use the terminal to launch the project details in a browser window.
❯
nx show project my-workspace --web
my-workspace
Root: .
Type: Library
Targets
lint
eslint ./src
Cacheablebuild
next build
Cacheabledev
next dev
start
next start
The project detail view lists all available tasks, the configuration values for those tasks and where those configuration values are being set.
Configure an Existing Script to Run with Nx
If you want to run one of your existing scripts with Nx, you need to tell Nx about it.
- Preface the script with
nx exec --
to havenpm run test
invoke the command with Nx. - Add the script to
includedScripts
. - Define caching settings.
The nx exec
command allows you to keep using npm test
or npm run test
(or other package manager's alternatives) as you're accustomed to. But still get the benefits of making those operations cacheable. Configuring the test
script from the example above to run with Nx would look something like this:
1{
2 "name": "my-workspace",
3 ...
4 "scripts": {
5 "build": "nx build",
6 "lint": "nx lint",
7 "test": "nx exec -- node ./run-tests.js"
8 },
9 ...
10 "nx": {
11 "includedScripts": ["test"],
12 "targets": {
13 "test": {
14 "cache": "true",
15 "inputs": ["default", "^default"],
16 "outputs": []
17 }
18 }
19 }
20}
21
Now if you run npm run test
or nx test
twice, the results will be retrieved from the cache. The inputs
used in this example are as cautious as possible, so you can significantly improve the value of the cache by customizing Nx Inputs for each task.