In this blog post I will go over the details of how we manage and publish packages inside our Telescope monorepo.
David recently shared a link where I found a good definition for monorepo that I wanted to share:
A monorepo is a single repository containing multiple distinct projects, with well-defined relationships.
Within Telescope, we have just that:
└── src
├── api
├── backend
├── docs
├── mobile
└── web
We have all of the APIs, backend, frontend, mobile app and the new Docusaurus docs all inside the same repo.
We recently made the switch to Turborepo and to try out its features, I have changed the way we lint our project. We used to run eslint from the root of Telescope, but now we have individual .eslintrc.js
files inside each project and let Turborepo manage it all.
Since version 1.1, Turborepo config moved from package.json
to its own turbo.json
file.
This is our turbo.json
that defines the lint
command inside its pipeline
:
{
"pipeline": {
"build": {
"dependsOn": ["^build"]
},
"lint": {
"outputs": []
}
}
}
When we run pnpm turbo run lint
, Turborepo will go over each package defined in pnpm-workspace.yaml
and run the lint command. This process is very efficient because it keeps a cache and reuses it if there are no changes to the files in the project.
For example, if I make changes to the docs, Turborepo will only run eslint in the docs, and use the previously created cache for everywhere else.
We have a new @senecacdot/eslint-config-telescope
package that contains the rules we reuse with every .eslintrc.js
and it lives inside the tools
directory:
└── tools
└── eslint
├── index.js
└── package.json
This package is published to the npmjs registry. To call it inside a .eslintrc.js
file we use extends
:
module.exports = {
extends: '@senecacdot/eslint-config-telescope',
overrides: [
// more rules here
],
};
Since @senecacdot/eslint-config-telescope
lives inside the monorepo, we have automated the release of the package thanks to pnpm publish.
Release to npmjs registry
There is a GitHub Actions workflow that handles the release of Telescope and, at the end of it, I added:
- uses: pnpm/action-setup@v2.0.1
with:
version: 6.30.1
- name: NPM Publish
uses: actions/setup-node@v2
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- run: pnpm install
- run: pnpm -r publish --no-git-checks --access=public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
The key part here is pnpm -r publish
. The -r
stands for recursive: pnpm will go look at each package.json
to see if a package has an updated version and, if so, will publish it to the registry.
Top comments (1)
Thanks for this. I've been fighting lerna publish + github actions for a week now and it turns out the solution was to just switch from npm to pnpm for the publish command.