Convert from a Standalone Repository to a Monorepo
You can always add another app to a standalone repository the same way you would in a monorepo. But at some point, you may want to move the primary app out of the root of your repo because the repo is no longer primarily focused on that one app. There are other apps that are equally important and you want the folder structure to align with the new reality.
Run the Generator
The convert-to-monorepo
generator will attempt to convert a standalone repo to a monorepo.
❯
nx g convert-to-monorepo
If you need to do the conversion manually, you can follow the steps below.
Manual Conversion Strategy
For this recipe, we'll assume that the root-level app is named my-app
. The high-level process we'll go through to move the app involves four stages:
- Create a new app named
temp
underapps/temp
. - Move source and config files from
my-app
intoapps/temp
. - Delete the files for
my-app
. - Rename
apps/temp
toapps/my-app
Steps
Update the
workspaceLayout
property innx.json
to be:nx.json1{ 2 "workspaceLayout": { 3 "appsDir": "apps", 4 "libsDir": "libs" 5 } 6} 7
This will make sure that new apps are created under
apps
and new libraries are created underlibs
.If there is a
tsconfig.json
file in the root, rename it totsconfig.old.json
This step is to make sure that a
tsconfig.base.json
file is generated by the app generator in the next step.Create a new app using the appropriate plugin under
apps/temp
❯
nx g app apps/temp
Move the
/src
(and/public
, if present) folders toapps/temp/
, overwriting the folders already there.For each config file in
apps/temp
, copy over the corresponding file from the root of the repo.It can be difficult to know which files are root-level config files and which files are project-specific config files. Here is a non-exhaustive list of config files to help distinguish between the two.
Type of Config Files Root-level .eslintignore
,.eslintrc.base.json
,.gitignore
,.prettierignore
,jest.config.ts
,jest.preset.js
,.prettierrc
,nx.json
,package.json
,tsconfig.base.json
Project-level .eslintrc.json
,index.html
,project.json
,jest.config.app.ts
,tsconfig.app.json
,tsconfig.json
,tsconfig.spec.json
,vite.config.ts
,webpack.config.js
jest.config.app.tsjest.config.app.ts
in the root should be renamed tojest.config.ts
when moved toapps/temp
. Also update thejestConfig
option inproject.json
to point tojest.config.ts
instead ofjest.config.app.ts
.Update the paths of the project-specific config files that were copied into
apps/temp
.Here is a non-exhaustive list of properties that will need to be updated to have the correct path:
Config File(s) Properties to Check project.json
$schema
,sourceRoot
,root
,outputPath
,reportsDirectory
,cypressConfig
,lintFilePatterns
,index
,main
,tsConfig
,assets
,styles
,jestConfig
tsconfig.json
,tsconfig.app.json
,tsconfig.spec.json
extends
,outDir
,files
.eslintrc.json
extends
jest.config.ts
preset
,coverageDirectory
vite.config.ts
cacheDir
,root
,dir
Doublecheck that all the tasks defined in the
apps/temp/project.json
file still work.❯
nx build temp
❯
nx test temp
❯
nx lint temp
Move the
/e2e/src
folder to/apps/temp-e2e
, overwriting the folder already thereFor each config file in
apps/temp-e2e
, copy over the corresponding file from the root of the repo. Update the paths for these files in the same way you did for themy-app
config files.Update the
/apps/temp-e2e/project.json
implicitDependencies
to betemp
instead ofmy-app
Doublecheck that all the tasks defined in the
apps/temp-e2e/project.json
file still work.❯
nx lint temp-e2e
❯
nx e2e temp-e2e
Delete all the project specific config files in the root and under
e2e
Once the
project.json
file has been deleted in the root, renametemp-e2e
tomy-app-e2e
and renametemp
tomy-app
❯
nx g move --projectName=temp-e2e --destination=my-app-e2e
❯
nx g move --projectName=temp --destination=my-app
Update the
defaultProject
innx.json
if neededCheck again that all the tasks still work and that the
nx graph
displays what you expect.