Manage Your Monorepo With Rushjs Typescript

Nov 12th, 2021 - written by Kimserey with .

Rush is build orchestrator facilitating management of Javascript and Typescript monorepos. In today’s post we will look at the common functionalities used in daily development making developers life easier.

Install Rush

We start by installing the rush command globally:

1
npm install -g @microsoft/rush

Then we can initialise rush within the root of our monorepo:

1
rush init

This will create the rush.json file which contains the main rush configurations and a /common containing extra configurations.

Add A Repository

Once we have created our monorepo and initialised it with rush, we can create our first project.

1
pnpm init -y hello-world

Then we must add the project to the rush.json projects:

1
2
3
4
5
6
"projects": [
  {
    "packageName": "hello-world",
    "projectFolder": "hello-world"
  }
]

We can then run a rush update to update the project dependencies and make hello-world available in our monorepo as a package.

1
rush update

update is also used to update PNPM packages when package.json is changed.

Add Dependencies

To add dependencies to projects, we navigate to the project folder and use rush add -p:

1
2
3
4
5
6
7
cd hello-world
rush add -p express
rush add -p typescript --dev
rush add -p @types/express --dev
rush add -p @types/node --dev
rush add -p ts-node --dev
rush add -p nodemon --dev

Then create a hello world express server hello-world/index.ts:

1
2
3
4
5
6
7
8
9
10
11
import express from "express";

const app = express();

app.get("/", (req, res) => {
  res.send("Hello World");
});

app.listen(3000, () => {
  console.log(`App listening at http://localhost:${3000}`);
});

with the following tsconfig.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "compilerOptions": {
    "lib": ["es5", "es6"],
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "./dist",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "strictPropertyInitialization": false
  }
}

Just like npm install, we can then do a rush update to update all dependencies across the whole monorepo when doing a fresh clone. Instead of having to install dependencies on each and every project, rush update bubble up to the root to find the rush.json and update all dependencies of all the projects specified in the projects in rush.json.

Build Repository

We are now ready to build our project. To build our project we must first define a build script in our package.json:

1
2
3
4
  "scripts": {
    "start": "nodemon --exec 'ts-node src/index.ts'",
    "build": "tsc"
  },

We can then do a rush build from anywhere and all projects will get built:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
rush build

Found configuration in /home/kimserey/Projects/rush-example/rush.json


Rush Multi-Project Build Tool 5.56.0 - https://rushjs.io
Node.js version is 14.17.0 (LTS)

Found configuration in /home/kimserey/Projects/rush-example/rush.json

Starting "rush build"

Executing a maximum of 16 simultaneous processes...

==[ hello-world ]==================================================[ 1 of 1 ]==
"hello-world" completed successfully in 1.44 seconds.



==[ SUCCESS: 1 project ]=======================================================

These projects completed successfully:
  hello-world    1.44 seconds


rush build (1.47 seconds)

The build command is incremental and will only build project with files that have changed. To make a clean build we can use rebuild.

In a monorepo, we might have many projects and the project we work on my only affect a subset of the other projects. In order to build just the current project and dependency we can use the -t option of rush build:

1
rush build -t .

Run Project

Lastly we want to be able to run our project. Just like npm run [cmd], Rush provides rushx. Given our two scripts start and build, we can do:

1
rushx build

To build the current single project. And we can use

1
rushx start

to start the application. And that concludes today’s post!

Conclusion

In today’s post we looked at RushJS, a tool used to managed monorepos. We started by looking at how to initialise the repository, then how to create projects and register them into Rush. We then looked at how to add dependencies and finally completed the post by looking at how to build and run projects. I hope you liked this post and I’ll see you on the next one!

External Sources

Designed, built and maintained by Kimserey Lam.