Overview, pain points, highlights and tips
Lets start with an example.
Imagine you have a React application with a Button component — this button component needs to use a Text component (granular but just humour me for the examples sake):
// inside the
super-buttonNPM package + repo
import SuperText from 'super-text'
const SuperButton = props => (
<SuperText value="Click me!" />
export default SuperButton
// inside the
super-textNPM package + repo
const SuperText = props => (
export default SuperText
Each of these components live in their own repos and are their own NPM packages — they need to be maintained, versioned, and worked on by 20+ developers.
Lets say we have a consuming application of both of these components — if we wanted to update both of these components as part of a feature then we would have to make the changes to each, update tests, update the versions, commit the changes, get them code reviewed, publish the packages, update the consuming application and use them — phew.
But wait! You just realised your changes are slightly different to the requirements and/or it doesn’t work as expected — lets pretend these components are far more complicated or might involve complex styling etc. You’d have to redo that entire process again — if your team is busy maybe they won’t get around to code reviewing it, maybe you’ll be blocked for the next 2 hours and have to resort to reading Medium articles until they’ve unblocked you!
Lerna to the rescue! Lerna lets you construct your application into a very large repository of packages and apps (can all be renamed and configured); these apps are the consumers and the packages are the granular dependencies (SuperButton & SuperText above). When you’ve made all the changes required, you execute a command:
$ lerna run bootstrap
What this will do is go through all of your applications (in our self-named
apps folder)and symlink each apps dependencies to any local version found inside the
packages by using the respective packages name (and version!) in
package.json. Any that aren’t found in
packages will simply be installed from npm the same way you would anyway.
This is huge — it allows massive refactoring, updating and feature enrichment without the developer process headache. Make changes to your dependencies, bootstrap, check and implement them in your consumer apps and you’re done! Save the pull request until everything is ready.
Sounds great right? We initially though so then we ran into some headaches porting our large app over — we’ve mostly solved all of them:
package.jsonfile and specify the
--hoistflag in your bootstrap command. It’ll still take a while but it’ll greatly reduce the time taken.
$ lerna run testcommand goes through each package and runs the test script declared in
package.json— the issue here is it will spawn a test runner for every single instance it finds — in our case we had ~60 which ate our laptops up. It also meant that our syntax highlighting (passing/failing/warnings etc) were being omitted due to the test runs being spawn in seperate shell process.
We’re still getting used to Lerna, it’s been a rocky path of frustration but ultimately it’s worked out for the best. It was great for our project and it might just be great for yours.
Create your free account to unlock your custom reading experience.