DEV Community

Cover image for Rethinking the “One Ring To Rule Them all” Monorepo manager
Matti Bar-Zeev
Matti Bar-Zeev

Posted on

Rethinking the “One Ring To Rule Them all” Monorepo manager

In this post I stop and rethink whether a single solution to manage all my monorepo needs is the right choice to make or should I go by "the right tool for the job" approach.

In my recent article (“Lerna is no longer maintained. Now what? - Part 1”) I started migrating from Lerna to NX according to the requirements Lerna has in my Pedalboard monorepo.

One comment I got stated this by @guitarino:

Image description

Which made me 🤔 …

My workspaces, though could be managed by Lerna, are managed by Yarn Workspaces which makes a lot more sense and practically works far better. That and the fact I like the idea of the “right tool for the right job” made me go back to the drawing board.

If I go by this idea, why should Lerna or NX take care of running scripts across the entire project where it is clearly the responsibility of the solution managing my workspaces - Yarn.

Let’s see if yarn can handle this. A quick Googling and I find this:

https://classic.yarnpkg.com/en/docs/cli/workspaces#toc-yarn-workspaces-run

I’m replacing the NX call with the yarn workspace run command and checkiung how it goes.
What I had before is this:

"scripts": {
       "test": "nx run-many --target=test --all",
       "coverage": "yarn test --coverage",
       "lint": "nx run-many --target=lint --all",
       "build": "nx run-many --target=build --all",
       "publish:lerna": "lerna publish --yes --no-verify-access",
       "coverage:combined": "pedalboard-scripts aggregatePackagesCoverage && nyc report --reporter lcov"
   },
Enter fullscreen mode Exit fullscreen mode

And I will change it to this:

"scripts": {
       "test": "yarn workspaces run test",
       "coverage": "yarn test --coverage",
       "lint": "yarn workspaces run lint",
       "build": "yarn workspaces run build",
       "publish:lerna": "lerna publish --yes --no-verify-access",
       "coverage:combined": "pedalboard-scripts aggregatePackagesCoverage && nyc report --reporter lcov"
   },
Enter fullscreen mode Exit fullscreen mode

Everything works well except the “build” command. It fails because the “components” package does not have a “build” script. That’s a shame, since NX simply overlooked such cases and let them pass.
Let’s see what Yarn has to offer in that case…

Hmmm, it appears that the Yarn [foreach](https://next.yarnpkg.com/cli/workspaces/foreach) command knows how to deal with missing scripts.
But this plugin requires Yarn v.2 or above, so let’s do that upgrade real quick, following the instructions here:

After we have our Yarn set with the new version we can import the plugin which allows us to use the “foreach” command like so:

yarn plugin import workspace-tools

Now I can modify my root project’s package.json to be:

"scripts": {
       "test": "yarn workspaces foreach -p run test",
       "coverage": "yarn test --coverage",
       "lint": "yarn workspaces foreach -p run lint",
       "build": "yarn workspaces foreach -ptv run build",
       "publish:lerna": "lerna publish --yes --no-verify-access",
       "coverage:combined": "pedalboard-scripts aggregatePackagesCoverage && nyc report --reporter lcov"
   },
Enter fullscreen mode Exit fullscreen mode

The params I’m using for the build command are for running in parallel, which still takes the topological order into consideration and resolves dependencies first. The “v” is for verbose.

I’m checking all of my scripts and everything seems to be working as it did before, minus the need for NX to complete these tasks. Awesome!

This still does not mean I won’t need NX in the future but it makes a lot more sense to keep the concerns of the tools I use separated.

In general I’m not a big fan of “all-in-one” solutions ever since the days of “printer, scanner, copier” in the same hardware device. It really depends on the requirements one might have, but for my slim monorepo I feel that the big role Lerna plays (and plays well, may I add) which actually requires an alternative is bumping and publishing the packages versions.
This is something which NX are currently working on, as my tweet thread elaborates about:

Fresh from the @NxDevTools conf -
I've asked if they're going to attend the whole "publish" workflow Lerna has and the answer was that they are currently working on it. They have a few concerns there:
👇🏻

— Matti Bar-Zeev (@mattibarzeev) April 29, 2022

There are still aspects of NX which excite me, like custom generators, dependencies graph visualization etc. but the choice of the tooling will be done from now on with “the right tool for the job” in mind.

As always, if you know of other means of achieving what's written above, please make sure to share them with the rest of us :)

Hey! If you liked what you've just read check out @mattibarzeev on Twitter 🍻

Photo by Philip Swinburn on Unsplash

Discussion (4)

Collapse
alonseg profile image
Alon Segal

which version of yarn have you used?
one concern (IMO) is coupling the consumption of packages and publication of packages...

Collapse
mbarzeev profile image
Matti Bar-Zeev Author

yarn@3.2.0
You can also check the code on GitHub for more details.
I'm not sure I understand what you mean about the coupling of versions and publications. Can you elaborate?

Collapse
alonseg profile image
Alon Segal

yeah sure,
in the scope of package management we have consumption of packages (installing packages in your project) and publication of packages.

now let's say you use yarn to both install and publish packages, you are a little "stuck" with it... if in the future you see that installation time gets too long, it'll be harder (than if you used different managers to consume and publish) to use something else only for consumption (and the other way around for publication...)

not sure I got my point clear, lmk if so and I'll try to rephrase....

Thread Thread
mbarzeev profile image
Matti Bar-Zeev Author

Again, I'm not sure I fully understand your concern, but if I go with what I do understand -
Installing packages is one step and publishing package is another, they do not happen in parallel. There are faster package managers than others but I think that reaching the place where this is actually painful... it's quite a project then ;)
If I'm not mistaken you can configure Lerna (and I guess other solutions as well) to work with a certain package manager for publication...