Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rush] pnpm fails to resolve peer dependencies of workspace package #2820

Closed
Measy opened this issue Jul 20, 2021 · 8 comments
Closed

[rush] pnpm fails to resolve peer dependencies of workspace package #2820

Measy opened this issue Jul 20, 2021 · 8 comments

Comments

@Measy
Copy link

Measy commented Jul 20, 2021

Summary

pnpm fails to resolve peer dependencies of workspace package, is there any good way to solve this problem?

Repro steps

Expected result:
peer dependencies get resolve in host dependencies

Actual result:
peer dependencies fails to resolve

Details

Let's say I have packages email-page1-react17, email-page2-react16 and email-libs

Both email-page1-react17 and email-page2-react16 use email-libs by "email-libs": "workspace:*" from local,

email-page1-react17/package.json

{
  "name": "email-page1-react17",
  "dependencies": {
    "email-libs": "workspace:*",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}

email-page2-react16/package.json

{
  "name": "email-page2-react16",
  "dependencies": {
    "email-libs": "workspace:*",
    "react": "^16.14.0",
    "react-dom": "^16.14.0"
  }
}

email-libs/package.json

{
  "name": "email-libs",
  "peerDependencies": {
    "react": ">=16.9.0",
    "react-dom": ">=16.9.0"
  }
}

In this case, email-page1-react17 and email-page2-react16 run dev/build and can't resolve 'react', because it just link
pages project's node_modules email-libs to the source code location of email-libs, and there is no "react" or "react-dom"
Here is the repo show the case: https://github.com/Measy/rush-pnpm-peer-workspace

Is there any good way to solve this problem, thanks for reply!

Standard questions

Please answer these questions to help us investigate your issue more quickly:

Question Answer
@microsoft/rush globally installed version? 5.50.0
rushVersion from rush.json? 5.47.0
useWorkspaces from rush.json? true
Operating system? Mac
Would you consider contributing a PR?
Node.js version (node -v)? 14.17.3

Related : pnpm/pnpm#2174, pnpm/pnpm#3558

@D4N14L
Copy link
Member

D4N14L commented Jul 21, 2021

If I'm understanding correctly, you should be able to resolve your issue by adding react and react-dom to the devDependencies for the email-libs project, since it needs these during build but not at runtime (since they're satisfied by peerDependencies).

@Measy
Copy link
Author

Measy commented Jul 21, 2021

adding react and react-dom to the devDependencies for the email-libs project

@D4N14L thanks for reply!I think it can not resolve my issue.
I If add react and react-dom to the devDependencies in email-libs project,

{
  "name": "email-libs",
  "devDependencies": {
    "react": ">=16.9.0",
    "react-dom": ">=16.9.0"
  }
}

and then I got react 17.0.2 in email-libs project' node_modules.
But there will be some error in project email-page2-react16 because it has react 16.14.0 in it's node_modules
It occur issue

You might have more than one copy of React in the same app

image

That why I use peer dependency to make email-lib can use host project's dependency; Not only react, there may some other libs use peer dependency to resolve version conflicts.

@D4N14L
Copy link
Member

D4N14L commented Jul 21, 2021

Peer dependencies are simply a constraint, they do not instruct the package manager to install that package as a dependency. This is why you should add one version as a devDependency, since these will not be installed when using the published package but will be usable during build. It's not possible to satisfy dependencies of a project by both versions at the same time during build, so you would need to pick one version to target your build against.

I believe you may be able to add just the types as a devDependency and to your tsconfig to be able to build.

@Measy
Copy link
Author

Measy commented Jul 21, 2021

Yes,in my usually case, I also add one version as a devDependency,and specifies more a wider version scope in peerDependencies; As the example above,email-lib just a local shared library without published in monorepo workspace; email-page1-react17 and email-page2-react16 resolve email-lib symlinked to the source code location of email-libs, it's hard to pick one version of lib during email-page1-react17 and email-page2-react16 build process without use a published lib

@D4N14L
Copy link
Member

D4N14L commented Jul 21, 2021

Try adding the types without adding the dependency itself. This should allow you to reference react without actually including a version of react in your lib

@Measy
Copy link
Author

Measy commented Jul 21, 2021

Hi @D4N14L ,thanks for reply!

Adding the types can't solve this problem, it still can't resolve the react. I think the main point is package manager treat workspace packages different with npm packages(https://pnpm.io/how-peers-are-resolved).
Some modules like plugins and frameworks require using the same module instance either in development or build process, and in our workflow we add those libs in peerDependencies to make things right; But because it simple symlinked to the source code location, make shared library is resolving with devDependency package, rather than peerDependency; If you don't declare devDependency,you get an unresolved error. Treat workspace packages similarly to npm packages looks like more reasonable to me.
For now, may be I will follow zkochan suggest

And I guess the only solution in this case would be to make some script that would copy email-libs to another directory.
So you would have email-libs-react16 with react 16 in dev dependencies.
And you would have email-lib-reac17 with react 17 in dev dependencies. And some script would sync the source code of the two versions of email-lib.

or just make ConsistentVersions to avoid these issues. (I still hope package manager treat workspace packages similarly to npm packages 🤣

If you have any idea, please share to me ,thanks again!

@D4N14L
Copy link
Member

D4N14L commented Jul 21, 2021

I think zkochan is probably correct in this instance, and that should work for you. Using just the types might work if you use import type, but zkochans suggestion should work for sure. Closing out as issue is resolved.

@D4N14L D4N14L closed this as completed Jul 21, 2021
@Measy
Copy link
Author

Measy commented Nov 21, 2021

This issue is solved with the new dependenciesMeta.injected feature of pnpm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants