Kinga
Posted on March 2, 2022
After happily using Lerna for quite some time, I feel I should move on.
This article is a fully subjective review of Rush, outlining some pros and cons I find important for my SPFx projects. In the next articles of the series I will show my approach to some obstacles I see.
Rush
Rush is owned by Microsoft, and since January 2017 is an open source project. You may find a little history here.
.
Package Manager Support
Lerna | Rush ⭐ |
---|---|
✔️ npm ❌ pnpm ✔️ yarn |
✔️ npm ✔️ pnpm ✔️ yarn |
Can I rest my case now?
Pnpm is a big deal. It solves phantom dependencies and NPM doppelganger problems, and if that's not enough, it's also faster and users less disk space. There's a request for pnpm support by lerna, opened in 2018. I'm not holding my breath.
Monorepo management
Dependencies support
Lerna | Rush ⭐ |
---|---|
For monorepos, lerna bootstrap --hoist installs external dependencies at the repo root, so they're available to all packages.This increases the risk of phantom dependencies. |
Installs package dependencies in common/temp/node_modules and updates the shrinkwrap file in common/config/rush folder to store a central inventory of all dependencies and versions for projects in the repo. Rush uses symlinks to reconstruct an accurate node_modules folder for each project, based on the shrinkwrap file. |
Rush & phantom dependencies
Rush's symlinking strategy ensures that each project's node_modules contains only its declared direct dependencies. This catches phantom dependencies immediately at build time. If you're using the PNPM package manager, the same protections are also applied to all indirect dependencies (with the ability to workaround any "bad" packages by using pnpmfile.js).
Rush & doppelgangers
Rush's symlinking strategy eliminates doppelgangers only for dependencies that are local projects in the monorepo. If you're using NPM or Yarn as your package manager, unfortunately doppelgangers are still possible for any indirect dependencies. Whereas if you use PNPM with Rush, the doppelganger problem is fully solved (because PNPM's installation model accurately simulates a true directed acyclic graph).
Selectively build and publish
Yes and yes, although I find rush to give me more flexibility.
Lerna | Rush |
---|---|
lerna run --scope PROJECT build |
rush build [--to PROJECT] [--to PROJECT] [--from PROJECT] [--only PROJECT] [--impacted-by PROJECT] [--impacted-by-except PROJECT]
|
lerna publish Control which package should get published using "private": true or "private": false in the package.json . Private packages never get published.Use lerna publish --force-publish=package-2,package-4 to decide which packages get published. |
rush publish Control which package should get published using shouldPublish in rush.json . Use rush publish --include-all so that all packages with shouldPublish=true in rush.json or with a specified version policy will be published if their version is newer than published version. |
Independent versioning
Lerna | Rush |
---|---|
Configured in lerna.json |
Configured in common\config\rush\version-policies.json and also in rush.json
|
Versioning and Conventional Commits
This was a surprise.
Lerna ⭐ | Rush |
---|---|
lerna version --conventional-commits uses use the Conventional Commits Specification to determine the version bump and generate CHANGELOG.md files. Interestingly, chore commit will also cause version bump. |
Rush has entirely different approach here. Developers, apart from committing their changes, are required to run rush change command to generate change files. rush change prompts for a change description and a type of change (major/minor/patch). No Conventional Commits support, no use of commit messages. The change files are stored in common\changes folder and are later used to update changelog. |
Git hooks
Lerna | Rush ⭐ |
---|---|
Yes, with husky. | Yes, see installing Git hooks. |
I'm giving Rush a ⭐ here because it offers support, if the code invoked by git hook has dependencies on additional modules.
npm lifecycle support
Lerna ⭐ | Rush |
---|---|
Lerna runs npm lifecycle scripts during lerna version . |
There seems to be a problem, but I think I can overcome it with custom commands |
My decision
Lerna and Rush both have pros and cons. I really see a difference when using pnpm, so I'm going to stick with Rush.
I only have to solve the issue with changelog generation.
Posted on March 2, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.