why does yarn warn when adding a dependency to the root workspaces package.json

dagda1 picture dagda1 · Jul 8, 2018 · Viewed 17.7k times · Source

Whenever I add a dependency to the root of the workspaces project:

e.g.

yarn add assets-webpack-plugin -D

I get the following error:

Running this command will add the dependency to the workspace root rather than the workspace itself, which might not be what you want - if you really meant it, make it explicit by running this command again with the -W flag (or --ignore-workspace-root-check).

The alternative is to add it to every project that needs it and then it will you have the problem of each project having different dependencies and lock files.

Answer

Abdollah picture Abdollah · Nov 30, 2018

Since you are using Yarn Workspaces and it manages the dependencies of all projects (workspaces), you should add dependencies of each project to its own package.json, not the workspace root. Yarn uses only one yarn.lock file that is placed in the workspace root. Also, it tries to move dependencies of all projects to node_modules of workspace root to prevent duplication as much as possible. Although some dependencies need to be placed in node_modules of their own project; e.g. when the workspace root has a devDependency to [email protected] while a project has a dependency to the same package with another version, say 1.2.5 which they are not compatible. Suppose the directory structure of your workspaces is like the following:

├── workspace-root
|   ├── package.json
|   ├── workspace-a
|   |   ├── package.json
|   ├── workspace-b
|   |   ├── package.json

After running yarn either in the workspace root or in any workspace directory, you will have the following directory structure:

├── workspace-root
|   ├── node_modules
|   ├── package.json
|   ├── yarn.lock
|   ├── workspace-a
|   |   ├── package.json
|   |   ├── node_modules
|   ├── workspace-b
|   |   ├── package.json
|   |   ├── node_modules

Only add a dependency to workspace root when you want to run a script from workspace root and it needs a dependency. In this case, the projects are independent of that dependency, so you can ignore that warning.

Why does yarn warn?

If you add the common dependencies of the projects to the workspace root, it won't come in package.json of the projects. Therefore, if you separate a project, it won't have all of its dependencies in its own package.json so running yarn install for the separated project leads to not having all the dependencies in its own node_modules. Obviously the separated project cannot work and you need to fix the absent dependencies problem to resolve the issue.

More about Yarn Workspaces

Yarn Workspaces is a feature for the sake of easier managing dependencies of projects that are related to each other. For example, when your projects have similar dependencies, you can declare each project as a workspace. It prevents a lot of duplication. Another important use case is monorepos:

Those who have tried splitting a project into multiple packages know how hard it is to make changes across multiple packages at one time. To make the process easier, some big projects adopted a monorepo approach, or multi-package repositories, which reduces the burden of writing code across packages.

Several projects used every day by JavaScript developers are managed as monorepos: Babel, React, Jest, Vue, Angular.

Using Yarn Workspaces brings the following benefits:

  • It allows you to setup multiple packages in such a way that you only need to run yarn install once to install all of them in a single pass.
  • Your dependencies can be linked together, which means that your workspaces can depend on one another while always using the most up-to-date code available.

  • This is also a better mechanism than yarn link since it only affects your workspace tree rather than your whole system.

  • All your project dependencies will be installed together, giving Yarn more latitude to better optimize them.

  • Yarn will use a single lockfile rather than a different one for each project, which means fewer conflicts and easier reviews.