Using a Monorepo to Increase Sharing
This article covers organizing the TachyonCMS code into a monorepo and organizing things for maximum reuse. The goal is to make development smoother, but there are of course trade-offs.
I’ll be moving these three repos into one new monorepo.
Flow Server — https://github.com/TachyonCMS/flow-server
Desktop Editor — https://github.com/TachyonCMS/desktop-editor
Storage API — https://github.com/TachyonCMS/storage-api
New Repo
https://github.com/TachyonCMS/tachyoncms
Advantages
- Easier sharing of code between services
- Only one place to look for code
Disadvantages
- Lowest common denominator
- Noise
A mono repo has the most value when there is code that is shared between the various pieces. Increased sharing means increased dependencies, staying on the cutting edge exacerbates the issue. Resolving those dependencies can force you into compromises.
Examples:
- Quasar 2 breaks under Yarn 2 so we had to stick with Yarn 1.
- Electron breaks on importing
fs-extra
so we had to stick withfs
Step 1: Create a fresh repo
You can use any means to do that. I used the GitHub web interface to create the TachyonCMS mono repo.
Step 2: Check out the repo
git clone git@github.com:TachyonCMS/tachyoncms.git
Step 3: Define new directory structure
This is the directory structure we want in the root of the mono repo.
├── editor-ui - Quasar editor app for all clients
├── flow-server - Quasar SPA for static content
├── postman - Explanatory collections
├── shared - Shared between other pieces
│ ├── components - Vue3 Components
│ │ └── blocks
│ │ └── edit - Vue3 Block editor SFC
│ │ └── render - Vue3 Block view SFC
│ ├── content - Default contentRootDirectory
│ │ ├── flows - Demo/Test Flows
│ │ └── nuggets - Demo/Test Nuggets
│ └── modules
│ └── tachyoncms-fs - Access data from a file system
└── storage-api - Serves content data to Editor app
Step 4: Move code into the mono repo
Rather than copy local versions of the code we’ll check out clean copies from GitHub for each.
Clone the the desired branch from each repo into the desired directory in the mono repo. You can define the target directory name liked I did for editor-ui
or accept the repo name like I did for flow-server
git clone --depth=1 --branch=web-app git@github.com:TachyonCMS/desktop-editor.git editor-uigit clone --depth=1 --branch=main git@github.com:TachyonCMS/flow-server.git git clone --depth=1 --branch=main git@github.com:TachyonCMS/storage-api.git
Remove the .git
folders so they don‘t conflict with the main one.
rm -rf ./editor-ui/.git
rm -rf ./flow-server/.git
rm -rf ./storage-api/.git
The Storage API gets split up.
- The file system library becomes the primary artifact for the
tachyoncm-fs
root dir. - The `routes` and `server` files should do nothing more than route calls to the proper
tachyon-cms
methods. We want to avoid adding business logic in them because that logic probably needs to be implemented by anything using this module, so that functionality should be part of the file system module. i.e. A route should not call two functions.
Block editor and renderer code from the old desktop-client
gets moved to the shared
directory so that the exact same files can be used in the TachyonCMS Editor app and the Flow Server app, as well as in any future code.
Step 5: Using the mono repo
The shared
directory has code that is accessed by multiple other pieces of code.
TachyonCMS-FS
The TachyonCMS-FS allows managing TachyonCMS data files stored on a local drive. This is used by the Electron Editor UI and the REST Storage API.
This same file system module will be used by the Websocket Storage API and scripts that need to manipulate the data.
Render and Edit Blocks
The render blocks are used in both the Editor app and the the Flow Server. Other pieces of software that want to manage or display block data can reuse these.
Content
We provide a shared content directory. This is pre-populated with some data for demonstration purposes and new files get written and deleted from here during each test run.
When to NOT use a Monorepo?
I wrote an article on that as well.