Transitive dependencies (peer dependencies are not linked by lerna)
See original GitHub issueHello!
First of all, thank you for this great tool and your hard work.
However, I’ve encountered a problem, which I cannot find a way to untangle without using some nasty workarounds.
I have a monorepo with several packages, some packages are components, which I’m building using other packages. I’ve pictured all the important dependencies on the following image:
Rectangles are my local packages, ovals are third-party dependencies. Arrows show dependencies. Dashed arrow is a peer dependency.
The Component Package
is a package I’m trying to build.
The Bundler
is our internal build tool. It’s an orchestrator like Gulp or something.
Bundler
is using a Build Scenario
to run Rollup Processor
and compile the source code in the Component Package
. However, the Rollup’s configuration file as well as plugins configuration is stored inside of a Build Scenario
package, which depends on License Plugin
.
The License Plugin
requires the Rollup
under the hood in order to check it’s version. So, it’s a peer dependency for it. I’ve marked it with a dashed arrow in the image.
The Rollup Processor
is a package which actually depends on the Rollup
(which it executes).
When normal npm install
is done inside of the Component Package
, all dependencies are properly installed, i.e.: Component > Scenario > Processor > Rollup
. So when License Plugin
is trying to load the Rollup
it gets the installed version correctly.
The problem arises with lerna linking. When lerna links all the packages, the License Plugin
doesn’t get a link to the Rollup
, because it doesn’t depend on it directly, but only transitively through a peer dependency.
In the end, I can’t build the Component Package
, because the License Plugin
couldn’t find a Rollup
dependency.
Take notice, that I can’t make Rollup
a dependency of the Scenario
, because the scenario doesn’t care about an actual rollup version to use. It is controlled by the processor.
I think that lerna linking should take peer dependencies into account and try to link to them through the dependencies of the parent packages. In my example, it should see that License Plugin
is using Rollup
as a peer dependency and it should start looking for a package to link by resolving dependency chains from it’s parent Build Scenario
.
I know it looks complicated, but it’s a viable use case and it should be implemented in order to make such transitive dependency schemes work.
The “hoisting” feature could help here, but it’s too aggressive in my opinion and it has its own problems.
What do you think?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:7
- Comments:12 (4 by maintainers)
Actually, what yarn is doing is installing almost everything in the root
node_modules
, which is resolved correctly when scripts run from the various leaf nodes.Generally speaking, a package specified in
peerDependencies
should also be specified indevDependencies
. That’s how the pattern works for “traditional” npm packages, and in a monorepo it’s best to just install those peers in the root and let the node module resolution algorithm do the work.The best practice for monorepos, in my opinion, is to run all dev scripts from the root, not the leaf nodes. It helps reduce repetition, is often times faster, and avoids weird bugs like this.
@evocateur why are you closing this issue? It’s a legitimate problem. Your advice on “Just install the license plugin in the root” is a dirty workaround and not a proper solution.