Vencovsky
Vencovsky

Reputation: 31693

How to remove CRA from yarn workspaces?

I'm using yarn workspaces (Monorepo) and I added an already made create react app, but now, every time I need to build only one project from the Monorepo, it installs everything from create react app even though it won't be used.

What I need to do is keep everything from create react app in the node_modules from its own package and not in the root node_modules

How can I remove CRA dependencies from the shared dependencies of yarn workspaces?

For example, if I have a Monorepo like

- packages/
  - create-react-app
  - fooApp
  - sharedApp

When running yarn inside the create-react-app package, I want to install every dependency used from fooApp and sharedApp (this is a expected behavior of yarn workspaces) but when running yarn inside fooApp, I want to install every dependency from sharedApp but not create-react-app (which I can't, because it's installing dependencies from sharedApp and create-react-app).

Upvotes: 2

Views: 911

Answers (1)

ofhouse
ofhouse

Reputation: 3276

That looks like a case for yarn's nohoist feature!

As you described, yarn tries to pull every dependency required by a sub-package into the node_modules/ folder of the workspace root. That's because yarn is set out to produce a flat directory tree inside of node_modules/ to avoid installing multiple versions of the same package.

So your current structure would look like this after doing a yarn install:

workspace-root/
├── node_modules/
|    ├── react-scripts/ <- dependency of create-react-app
|    └── ...
├── packages/
|   ├── create-react-app/
|   |   ├── ...
|   |   └── package.json <- where the dependency comes from 
|   ├── fooApp/
|   └── ...
├── ...
└── package.json

What you want instead is a structure like this:

workspace-root/
├── node_modules/
|    └── ...
├── packages/
|   ├── create-react-app/
|   |   ├── node_modules/
|   |   |   ├── react-scripts/ <- dependency of create-react-app
|   |   |   └── ...
|   |   ├── ...
|   |   └── package.json <- where the dependency comes from 
|   ├── fooApp/
|   └── ...
├── ...
└── package.json

This is the exact use-case for nohoist: The option prevents yarn for certain packages to pull them into the workspace-root but rather keep them at the same level where they are required from.

What many people don't know is that the nohoist option can also be added to the child packages rather than the workspace root. Adding this to the the package.json of a child package in a monorepo prevents yarn from hoisting all of its dependencies to the workspace-root:

// packages/create-react-app/package.json
...
"name": "my-app",
"private": true,
"workspaces": {
  "nohoist": ["**"]
}
...

Upvotes: 1

Related Questions