Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Peer Dependencies In A Monorepo

When packages in a monorepo have peer dependencies, how should these dependencies be made available to them during development?

For example a package at /packages/namespace/alpha/ might have a devDependency of styled-components in its package.json.

Possible options:

  1. Declare the same dependencies as dev dependencies as well (unnecessary duplication and maintenance cost).

  2. Install the packages in the monorepo's route package.json (potential issues with module resolution when using yarn link.

I'm using Lerna with yarn workspaces.

like image 712
Undistraction Avatar asked Sep 20 '19 11:09

Undistraction


People also ask

How do you install peer dependencies in yarn?

Usage. Run npm install (or yarn install ) to install prod and dev , as well as peer dependencies. You still may see "unmet peer dependency" warnings, due to installation flow of npm/yarn. Also it won't update lock (shrinkwrap) files or modify package.

What is a peer dependency yarn?

Having a peer dependency means that your package needs a dependency that is the same exact dependency as the person installing your package. This is useful for packages like react that need to have a single copy of react-dom that is also used by the person installing it.

What is lerna Monorepo?

Introduction. Lerna is a tool for managing JavaScript projects with multiple packages. Lerna manages monorepos, which can hold projects containing multiple packages within itself. Monorepos can be challenging to manage because sequential builds and publishing individual packages take a long time.

What is peerDependencies in package JSON?

Peer Dependencies: In package. json file, there is an object called as peerDependencies and it consists of all the packages that are exactly required in the project or to the person who is downloading and the version numbers should also be the same. That is the reason they were named as peerDependencies.


1 Answers

Yarn workspaces should install almost everything in the root node_modules relying on node's module resolution algorithm. That is what you described in option 2.

So, basically it should work in most cases. The problems may occur when some tool relies on its own resolution logic or there are different versions of some dependency and so on.

Option 1 is a quite common approach but as you said it adds maintenance cost. You may need to keep track of such dependencies and mark them as external in order to avoid including them into the built version of the lib.

There are possible workarounds. For example, Angular suggests using TS paths option. And you can do pretty the same without typescript in, for example, Create React App using jsconfig.json. Or you can use something similar to this rollup plugin that automates adding externals basing on peerDependencies, so you can safely list them as devDependies as well.

Both options are considered legit in this lerna issue

Another option is to install your peer dependencies and as for now, there is no "official" solution for that. There is install peers cli package that works with npm and yarn. There is a hot feature request for yarn. There is a plan to add this feature to npm v7, actually npm did it before v3.

Wrapping up, there is no one-size-fits-all solution and you need to understand what you want to get and what you can sacrifice for that.

Update (14 Dec 2020) — NPM 7 installs peer deps

As I mentioned in the initial answer npm v7 implemented installing peer dependencies by default. Please refer to the RFC for further details.

like image 73
Shlang Avatar answered Sep 18 '22 23:09

Shlang