I had this repo called react and I used vite CLI to create my ReactJS app. But then I needed to add a simple NestJS backend to it. You guessed it right, a monorepo.
Thus I search in google to find out how others do this, First thing I faced was "Convert from a Standalone Repository to a Monorepo". This was not exactly what I needed. I mean sure it was converting a standalone repo to a monorepo but it was from Nx to Nx.
Not from Vite to Nx. Thus I continued my quest, looking for something more suitable. Then I found this Stackoverflow Q&A: "Migrating a Create React App (Webpack) to NX and Vite - URI malformed at decodeURI".
Yeah, fair enough. As its title is already screaming that it is not completely what I want but it has a very important info hiding inside the question.
We tend to over look or not even bother with reading the question which is IMO loosing a great opportunity. I mean we can learn several things by just spending 2 to 3 minutes to read the question:
- How to be succinct (if they're expressing what needs to be said without unnecessary details then we can learn from that, and if it is written very long, often with unnecessary details and falling into trap of XY problem we can again learn from their mistake and not fall victim to the same shortcomings).
- How to read.
- And sometimes like now even find your answer from the seemingly unrelated question.
OK back to the main topic, in the question it says:
I've created a blank project and began moving the projects one by one...
That was what broke the camel's back for me, I was too much thinking one sided. I thought there should be a tool to convert your existing Vite app to Nx standalone repo or monorepo. Like NestJS.
In NestJS if you have a monolithic NestJS app you can simply convert it to a monorepo (of course if you're using NestJS CLI and no other tooling is involved) by simply running this command: nest g app my-harmony-os
.
It will create a new NestJS app for you that is separated from the original app (let's say you've created it like this: nest new my-huawei
😉).
Let's get into what we need to do
-
create a new Nx/vite project somewhere in your OS:
npx create-nx-workspace@latest --preset=react-standalone --name=react --bundler=vite --pm=pnpm
.Answer those question about testing stack, CI pipelines and CSS preprocessors based on your own needs.
I am also a huge fan of pnpm, so that's why you see it there.
Also feel free to change the name of your workspace to whatever it should be, in my case it is the name of my repo: "react".
-
cd react && rm -rf .git
. I did not want to break my commits, thus I copied the.git
first from the original standalone Vite app.But you can also opt for something more democratic like keeping the created
.git
and merging it on GitHub into main. It is up to you. -
Then move your Vite app into the new structure.
I intentionally did not go for a monorepo first. I deliberately decided to first create a simple standalone ReactJS app in Nx and then convert it to monorepo + a NestJS app.
What I did personally was supper simple, first I moved conf files; things like
.prettierrc
,.gitignore
, etc. After that I ran
nx serve
to make sure my changes did not break anything.-
I committed my changes 😱! Do not panic, I have everything in my control.
First of all in step 2 I said I copied my old
.git
. Because there I was in a branch called "convert-to-monorepo". Thus when I merge back to my main I will squash all commits into one.Thus we can still rollback to this commit and expect our app to work.
Second, I did this to make sure if I converted my standalone repo to a monorepo and something went wrong I can still compare changes and be able to debug.
Or at least to be able to undo my changes and start again 😊.
nx g convert-to-monorepo
to convert my standalone ReactJS app into a monorepo.I repeated step 4 again.
-
And was busted by a scary looking error. Thus after 30 min going back and forth;
- Upgrading my global nx to latest version.
- Then trying it out again in
/tmp
so to see what is wrong.
I successfully get working (I even opened an issue for them to improve their
convert-to-monorepo
generator so that when you try it it will be a much more smoother exp).But yes,
- I had to manually fix my
eslint.config.js
issues. - Then I converted
eslint.config.js
to typescript. - I added
"type": "module"
to mypackage.json
.
Repeated step 4.
It was working. Committed my changes again.
Moved my main files.
-
Add my NestJS app:
nx g @nx/nest:app apps/my-huawei
.Then like what we did before you need to fix some mistakes. like if you've changed your
eslint.config.js
toeslint.config.ts
you need to remove the newly createdeslint.config.js
in your root dir.We've added
"type": "module"
to ourpackage.json
which is gonna now break our NestJS app build thanks to the fact that Webpack do not support ESM 😤 (open issue on GitHub for 2 years, I am not sure what they are doing but probably until nobody supports CommonJS they won't fix this issue 😑).
Important
After you move your files to the Nx you might need to make some adjustments to your codebase. For example I was importing my CSS files for each component.
But while I was converting to Nx I converted all of them to CSS modules, therefore I needed to specify each element's claasName
attribute:
import style from './Stopwatch.module.css';
//...
<section className={style.stopwatch} >
Note: Like I mentioned it, it was a conscious decision, meaning your component will work without doing that too. I mean just name it whatever you like (BUT not *.module.css
and import it: import 'whatever.component.css';
) and it will just fine.
So that's gonna do it for now. Happy coding in your new monorepo env. Lemme know if you hit a blocker.
Love my content? Share it, give me a star on GH for my react repo.
Find me on social medias:
Instagram: https://www.instagram.com/node.js.developers.kh/
Facebook: https://www.facebook.com/kasirbarati
X: https://x.com/kasir_barati
YouTube: https://www.youtube.com/@kasir-barati
GitHub: https://github.com/kasir-barati/
LinkedIn: https://linkedin.com/in/kasir-barati