Managing a Monorepo with Lerna
source link: https://www.tuicool.com/articles/hit/ZzqaUrQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Monerepo with lerna
At Kudobuzz we have lots of services in N odes,js , this naturally comes with writing many reusable packages.
Now in such a situation, the most obvious way to manage these packages is to have one repo per package, but we soon found out that didn’t work quite well with us.
Setting up a ci environment for each package/repo was frustrating.
When a change required that several packages be updated, it meant that we were going to have lot of pull requests instead of a single one.
After considering other solutions we decided to give Lerna a try.
Lerna helps you manage JavaScript projects with multiple packages.
This means if you have many services in Node.js you can basically have all of them in one repo. There are quite a number of js projects like Reactjs, Angularjs , NestJs and Shopify using it for similar reasons.
Let’s give it a try :)
We going to build a home for your organizations reusable Node.js packages. The name for our imaginary organizations will be Spot .
To get started we will install Lerna, create a folder called reusable-node-packages and then initialize Git and Lerna.
Scaffolding
sudo npm install lerna -g && mkdir reusable-node-pacakages && cd reusable-node-packages && git init && lerna init -i
Observations
// The following files will be created
packages.json // Configuration file for npm lerna.json // Configuration file for lerna packages/ // Folder for all reusable package
// Inside lerna.json { "packages": [ "packages/*" ], "version": "independent" }
The most important thing to take note of is Lerna basically has two modes: independent and fixed. Fixed mode keeps all the versions of the packages at the same level. We don’t want to do that in current project , @spot/queue and @spot/logger will definitely require different versions.
Let create @spot/queue and @spot/logger
lerna create -y @spot/queue && lerna create -y @spot/logger
Observations
// Packages folder now contains queue and logger folders // You can change the structure if you don't like this boilerplate
queue/ README.md __tests__/ // All test can go here logger.test.js // Test for logger.js package.json lib/ logger.js
logger/ ...
Now we can go ahead and work on the individual packages. :)
Setting up Testing with mocha and chai
npm install mocha chai --save-dev
Observations
Well this is not exactly specific to Lerna , “node_modules” will be created in the root folder and now each package under packages will have access to the dev packages we just installed.
Update your package.json to include
{ scripts:{ test: "mocha \"packages/**/*.test.js\" // This allows you to run all your test in every package }
You can simply run that command using npm test. Something that comes up once in a while is how I can run test just for a specific package during development. Include a similar test script for @scope/logger and @scope/queue.
{scripts: { test: "mocha lib/*.test.js"}}
To run test for @spot/logger package you can now use
lerna run test --scope logger
Publishing
To publish the individual packages, you can use the following
Observations
Lerna will detect changes to any of the packages and then walk you through bumping the versions for the packages that have changed before they are eventually deployed. This is a life saver, you no longer have to visit each package just to publish them.
In Conclusion
Lerna really improved our workflow, we no longer have to deal with multiple repos containing different packages, setting up ci for each of them anytime someones wants to add a new package and finally no more multiple pull request.
I hope you find this useful, Check out the final repo .
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK