- Published on
Getting Lerna Working With an Existing Create React App
- Authors
- Name
- Yair Mark
- @yairmark
The Issue
We have been using our own hand-rolled monorepo structure for our full stack JavaScript projects. This looks something like this:
package.json
-> ui
-> package.json
-> ...
-> server
-> package.json
-> ...
The package.json
in the root of the project has scripts that help you control the rest of the project from the root. It is not as easy to use as Lerna but we opted going this route due to running into issues when using Lerna with Create React App (the ui
folder above).
Searching for solutions many suggest ejecting your CRA but I would rather not have to worry about webpack, babel and other configs unless I have to.
Fixing It For the UI
Today I attempted to move one of our monorepos with CRA in to Lerna and succeeded by following this article with a few adjustments to get it to work with an existing CRA app. I opted for this route so that I could create a common module in my monorepo to easily share boilerplate utilities between the ui
and server
without having to copy/paste or go through the process of setting up a private npm registry.
The steps I used to migrate my existing repo and incorporate what was mentioned in the above article are:
- Init Lerna: From the root of the project I ran:
npx lerna init
- This creates the
lerna.json
file in the root and thepackages
folder which will hold your sub-repos
- This creates the
- Move the existing ui and server repos:
mv ui packages && mv server packages
- Use Lerna to Install React at the top level:
npx lerna add react@^16.6.3 && npx lerna add react-dom@^16.6.3
- In this case I made sure the versions I was installing matched those in my
ui
'spackage.json
file
- In this case I made sure the versions I was installing matched those in my
- Clean and Hoist: As per the article I then ran:
lerna clean -y && lerna bootstrap --hoist
I confirmed this worked by running: lerna run start --stream
which starts both the ui
and the server
in the same shell showing the outputs for both.
Babel Issues
The whole point of the above move was to allow me to share utilities between my ui
and server
. This worked perfectly when sharing from my common
utility module to the ui
but I still need to tinker with babel at the root to get it allow me to import common
utilities in the server
module. The steps I used to create the common
module were:
# from the monorepo root (where the lerna.json) is run:
lerna create @my-awesome-project/common -y
In the above you can use whatever you want after the create
but I used the name of my monorepo with an @
before it.
Other Issues
Yarn does not play nice with lerna
and create-react-app
- I kept running into the original issues that kept me away from lerna
. As a result I stuck to using npm
. Also if you switch to yarn
you lose the ability to hoist
using Lerna and it looks like you end up having to use a mix of yarn workspaces and lerna.
Conclusion
As it stands this setup will work perfectly for creating a common module between one or more create react app sub-repos. It does not work when trying to import common modules into sub-repos that are not cra apps, some babel tweaking is needed still to get this to work. The other none-cra apps will still work correctly with lerna as long as you do not need to import common
module items. Hopefully after a bit more digging I will get this to work too.