How do you structure a project that is modular and has many dependencies? Also, you are responsible for releasing it. You need to test, build, and publish all of them?
One of the solutions for this is to create a Monorepo!
Node on Rails development structure
The goal for node-on-rails is to be modular. In the Javascript/Typescript world, this means to separate them into packages. Every module/component/plugin name it, as you want, will be its small package. At the start, there will be only two packages the cli
package and the core
package. The two will not be alone for a long time, and the build process and publication should be easy. So okay at some point, we can have N
packages, but we want just one repo for it!
What is a Monorepo?
Let's have a look what Wikipedia is saying:
In revision control systems, a Monorepo is a software development strategy where code for many projects is stored in the same repository. As of 2017, this software engineering practice was over a decade old but had only recently been named.
Okay, that helps a little bit, but not really 🤷♂️.
Monorepo can mean a lot, and you can see different types of them out there on GitHub. Let's go through some kinds of Monorepos:
A Company Monorepo: The most famous Monorepo lives at Google. According to insiders, every line of code at google is in this Monorepo. Billions of lines of code in one repo! Crazy.
A Project Monorepo: Here, you have all the code needed for your project. Backend, Frontend, Scripts, and everything else needed for that specific project. This can be documentation, configs, and many other things. This style of Monorepo is a good fit if you have a product and want everybody for
that project to have all the information and code needed with one single cloneA Package Monorepo: The Monorepo where you have a collection of (npm) packages. All the packages are part of a bigger system. You can have all parts of the system in its package, and you can release every package on its own. You manage them all in on repo.
There are probably more types of Monorepo's.
It should now be clear what type we will use for node-on-rails. The 'Package Monorepo'.
How to set up a Monorepo?
For now, we will use yarn workspaces
. There is also Lerna
, which is probably the most popular Monorepo tool. If needed, we will add it later.
The first thing we need to create is a root folder.
mkdir node-on-rails
In the newly created node-on-rails
folder, we need to create a package.json file with the following JSON inside:
{
"private": true,
"name": "node-on-rails",
"workspaces": [
"packages/*"
],
}
The "private" key will prevent us from publishing the root package to the public. The name is optional, but I still like to add it.
The last three lines are the most interesting here. This is where we define our workspaces. It is an array of folder paths. All of our packages will be in the packages
folder so we can use the *
operator to tell yarn
that we want all subfolders to be a workspace.
Let's now create our two first package folders with:
mkdir -p packages/CLI packages/core
To keep this post short, we will create one of the package.json's, but you can, for a start, copy and paste it.
Now we will create a package.json
on the node-on-rails/packages/core
folder. with the following things inside:
{
"name": "@nor/core",
"version": "0.0.1",
"dependencies": {
"typescript": "^3.7.4"
}
}
You can do the same in the node-on-rails/packages/cli
folder.
Let's install all the dependencies:
yarn install
Yes! That's it. This will install all the dependencies on all the workspaces!
If you now want to run a npm script in a workspace you can either cd
into it or do the following:
yarn workspace @nor/CLI run test
or if you, for example, want to run all tests in all packages you can enter:
yarn workspaces run test
Bonus: Update all npm dependencies
If you don't want to update all your package by hand, you need to install
npm-check-updates
with:
sudo yarn global add npm-check-updates
and add the following script to your root package.json
"scripts": {
"upgrade:all": "find . -type f -name 'package.json' -not -path './.git/*' -not -path '*/node_modules/*' -execdir ncu --upgrade \\;"
},
That is all for this post. I hope you now have a better understanding of what a Monorepo is and how to create one.
If this added any value for you, please consider sharing this post on twitter or any other social media. I would be the happiest person on earth.🙏😀
👋Say Hello! Instagram | Twitter | LinkedIn | Medium | Twitch | YouTube
Top comments (7)
Why node-on-rails ? Too much clickbait. You should understand if people look at you as a source of clickbait articles, you'll loose your audience. Please try to avoid that.
Node on Rails is the name of the ongoing project. This article is an extension of how Node on Rails is being developed and why. He labeled it that way, as someone who also came up with this concept inspired by RoR, I'm happy to soon help develop it. You should check it out it's in early development.
I had an previous blog post talking about why node-on-rails.
I have added them both now a series. So you should be able to see the first blog post linked here.
The short answer is: No the name is exactly what I wanted it to communicate to the user -> This project is about implementing a framework like RoR in nodejs. This and more is explained in the first blog post.
There will be also more blog posts on the journey of developing this framework. This was just the first one with real code examples.
I tried both yarn and lerna for monorepos and both were fine until I discovered pnpm. Give it a try, it's awesome!
isn;t pnpm another package manager like npm and yarn? 🤔
Yes, but it also has built in monorepo support, similar to yarn
Okay thanks for the info :)