This document is a short description of the monorepo setup that I came up for a few different smaller projects in the last 8 months or so.
/
services/
product/
topup/
...
.dockerignore
.gitignore
.gitlab-ci.yml
README.md
docker-compose.yml
package.json
yarn.lock
We can use GitLab CI as we already do, merging X small-ish existing GitLab CI config files into one larger one.
The only
property makes it easy to only run test or deploy the services that actually changed.
image: node:10-alpine
stages:
- test
test purchase service:
stage: test
services:
- mongo:3.4
- redis:4
only:
changes:
- .gitlab-ci.yml
- services/topup/**/*
script:
- cd services/topup
- yarn install --pure-lockfile
- yarn test
Why? Because yarn comes with monorepo support out of the box: See Yarn workspaces.
A simple top-level yarn install
will install the dependencies of all services as well and if you have packages referencing each other,
it will also automatically link them against each other.
Nice side effect: It installs dependencies faster and does not constantly modify the lock file while nothing changed.
Lerna is a handy tool to manage monorepos. You can easily:
- Run a package.json script in every service / package
- Can run scripts and commands either in parallel or serially
- Publish all packages at once or only those that changed (if a package monorepo)
Alternative: oao
Small npm package that is run from CLI on monorepo-wide yarn install
. Creates symlinks to the monorepo-wide node_modules/.bin/*
in all service directories. Otherwise executing those tools from a service's package.json scripts might fail.