old greg
old greg

Reputation: 897

How do I add shared dependencies to a monorepo using Yarn workspaces?

I am using Yarn's Workspaces feature to manage a monorepo. Some of the individual workspaces have their own dependencies defined in their own package.json, however I also have some shared dependencies (some are for testing the whole repo, some are used by all the workspaces). How do I declare these the correct way?

If I try to add them to the root package.json, Yarn gives me a warning. But adding the same dependency to all n workspaces (there are a lot and it's liable to grow) seems tedious and hard to maintain when upgrading dependencies.

Is the right thing to do to add the shared dependency (say, typescript, or jest or serverless) to every single individual workspace?

Using Yarn 1/classic.

I found also Yarn Workspaces: How and where should I install my dependencies? but it's unanswered Yarn workspaces shared dependencies talks about using peer dependencies but the user is experiencing trouble

Upvotes: 16

Views: 20184

Answers (1)

WcW
WcW

Reputation: 511

After a half-day search and trying, I found multiple ways to manage shared dependencies

1. Sync dependency version with syncpack

https://github.com/JamieMason/syncpack/

Given the fact that yarn workspaces will share the dependencies if their versions are the same (see https://classic.yarnpkg.com/lang/en/docs/workspaces/), all we have to do is to keep the dependency versions in sync to make dependencies sharing, which is exactly what syncpack does.

I found this is the least harmful way to make sharing dependencies works, while other methods require some degree of twisting package.json.

2. Use peer dependencies

For each package, set sharing dependencies as peerDependencies with version “*”, and set root workspace set the real dependencies. For example:

# ./package.json
{   
    ...
    "workspaces": ["packages/*"],
    "dependencies": [
        "some-lib": "^1.0.0",
    ]
}

# ./packages/pkg-a/package.json
{
    ...
    "peerDependencies": [
        "some-lib": "*",
    ]
}

and yarn install at workspace root.

3. Share script (require yarn v2)

See https://yarnpkg.com/getting-started/qa#how-to-share-scripts-between-workspaces

Miscellaneous

yarn provides workspace cli to add/remove package, see https://classic.yarnpkg.com/lang/en/docs/cli/workspace/

yarn workspace awesome-package add react react-dom --dev

yarn workspace web-project remove some-package

Upvotes: 19

Related Questions