OnlineOrNot Diaries 9
Max Rozen (@RozenMD) / April 29, 2023
Another Saturday morning here in Toulouse, let's go into how OnlineOrNot went this week.
It was a coding week (that makes it three in a row, for those counting at home), and I took the time to clean-up a ton of tech debt. This article gets a little bit technical.
For context, I launched OnlineOrNot approximately two years and two months ago, and I never really treated the code like it might stick around for a while. A lot of my git commit messages are just me swearing. These are things you can get away with when you know you'll be the only person reading your code.
I built OnlineOrNot as a "mono-repo", but the folder structure was pretty chaotic, and if I wanted to use packages, I had to publish them to npm. I had the main Next.js app in one folder, a folder for my terraform configuration, and every AWS Lambda function in another:
infrastructure/lambdas/| |-- browser-checker/| |-- checker-scheduler/| |-- cron-tasks/| |-- uptime-checker/| |-- uptime-checker-runner/| |-- weekly-emails/| |-- ...more lambdas hereweb/
For a long time that worked well. There were a couple of utility functions I copy pasted between lambda functions, and I had comments to remind me to update the code in multiple places (obviously not a great practice when you have a team), and never had any issues.
Adding fly.io complicated things
At some point last year, I duplicated OnlineOrNot's stack and made it run on fly.io. The resulting folder structure looked like this:
infrastructure/fly/| |-- checker-scheduler/| |-- uptime-checker-runner/| |-- ...more apps herelambdas/| |-- browser-checker/| |-- checker-scheduler/| |-- cron-tasks/| |-- uptime-checker/| |-- uptime-checker-runner/| |-- weekly-emails/| |-- ...more lambdas hereweb/
The trouble with this is, a good 95% of the code between the fly.io and AWS versions of OnlineOrNot were the same, adding a significant amount of code duplication. I figured it wasn't such a big deal at the time, since I'd just delete the AWS code one day, but then I realized OnlineOrNot could survive a hosting provider outage by keeping both stacks online.
So the duplicated code had to stay, until I had time to clean it up properly.
Moving to a "real" mono-repo
Since OnlineOrNot is mainly written in Node.js, I actually had a relatively easy way to split up code into packages that can be shared between apps: npm workspaces.
The gist of the change was:
Run
npm init -y
in the root of my mono-repo, and add a workspace config to the package.json:"workspaces": ["apps/*""packages/*",],Move all the apps into the
apps/
folder, and cut common code out of apps, and move them into their own packages in thepackages/
folder
In the end, it looks like this:
infrastructure/apps/| |-- checker-scheduler-aws/| |-- checker-scheduler-fly/| |-- uptime-checker-aws/| |-- uptime-checker-fly/| |-- web/| |-- ...more apps herepackages/| |-- common-queries/| |-- time-utils/| |-- ...more packages here
With the old folder structure, things were starting to feel a bit risky: if I updated duplicated code in one place but not others, parts of OnlineOrNot could behave differently as I changed hosting providers.
With the new structure, I don't even need to publish packages to npm to use them in my apps - it Just Works quite nicely.