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

Add a means to install package peer dependencies for development / testing #1503

Open
jshthornton opened this issue Oct 27, 2016 · 72 comments

Comments

@jshthornton
Copy link

@jshthornton jshthornton commented Oct 27, 2016

Do you want to request a feature or report a bug?
Feature

What is the current behavior?
N/A

What is the expected behavior?
Provide a CLI command yarn install --peer which will install peer dependencies specified in package.json. That way development / testing can use the peers such as react/ng2/grunt.

@wyze wyze added the cat-feature label Nov 3, 2016
@jpollard-cs

This comment has been minimized.

Copy link

@jpollard-cs jpollard-cs commented Nov 4, 2016

according to the docs this should exist via yarn add <package name> --peer, but I am not finding that it works (https://yarnpkg.com/en/docs/cli/add#toc-yarn-add-peer-p)

@jpollard-cs

This comment has been minimized.

Copy link

@jpollard-cs jpollard-cs commented Nov 4, 2016

reference for this issue: airbnb/react-dates#14 (per @coreylight's comments it seems yarn add react-dates -P still complains about peer dependencies that are unmet. Anyone that can shed some light on this? Perhaps the command is being used wrong?

@jshthornton

This comment has been minimized.

Copy link
Author

@jshthornton jshthornton commented Nov 9, 2016

@jpollard-cs I am not referring to adding a package as a peer dependency, I am referring to having a means to install all packages currently listed as peer dependencies.
Otherwise there is not a viable means of developing plugins.

@esutton

This comment has been minimized.

Copy link

@esutton esutton commented Nov 9, 2016

npm install
Would install all packages declared in package.json dependencies section.

yarn add --peer
I expected this to install all packages declared in package.json peerDependencies section.

Is there a way to install a declared packages in peerDependencies?

My use case is development / testing of a react native module.

@jpollard-cs

This comment has been minimized.

Copy link

@jpollard-cs jpollard-cs commented Nov 10, 2016

@jshthornton ah that's why that command didn't work as I expected

@oliverjanik

This comment has been minimized.

Copy link

@oliverjanik oliverjanik commented Nov 29, 2016

Here's NPM issue, which they closed: npm/npm#11213

Apparently not important to NPM devs.

@gf3

This comment has been minimized.

Copy link

@gf3 gf3 commented Jan 30, 2017

+1 this is important for library authors

@nathanhleung

This comment has been minimized.

Copy link

@nathanhleung nathanhleung commented Mar 10, 2017

I already wrote this on the NPM issue, but for Yarn people:

I wrote a cli program install a package's peer dependendencies:

# If you're using npm
npm install -g install-peerdeps

# If you're using yarn
yarn global add install-peerdeps

cd my-project-directory

install-peerdeps <package>[@<version>]

# for example
install-peerdeps @angular/core
# will install all of angular's peerdeps

If you have any problems with it please open an issue on the repo!

@jshthornton

This comment has been minimized.

Copy link
Author

@jshthornton jshthornton commented Apr 11, 2017

@nathanhleung, that package appears to install all of your dependencies peer dependencies. Which isn't quite what this ticket is about. This about installing your own package's peer dependencies.

I have fixed it with a package to do that https://www.npmjs.com/package/@team-griffin/install-self-peers

@LyzioOh

This comment has been minimized.

Copy link

@LyzioOh LyzioOh commented May 1, 2017

@nathanhleung you rocks.

kohlmannj pushed a commit to kohlmannj/jss-simple that referenced this issue May 5, 2017
@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented May 15, 2017

Hmm... If one needs dependencies for development / testing, shouldn't one put them under devDependencies? Not trying to drop a bomb or anything...

@keyboard-clacker

This comment has been minimized.

Copy link

@keyboard-clacker keyboard-clacker commented May 22, 2017

@nikolakanacki Totally see where you're coming from, I think the weirdness is that it'd be both a peer dependency and dev dependency, since you should never force your consumers installing your dev dependencies. I vote making it easy to install peers!

@alexilyaev

This comment has been minimized.

Copy link

@alexilyaev alexilyaev commented Jun 12, 2017

@nikolakanacki If you author a package that relies on another package that the user installs, you don't want it in devDependencies, that may result in a duplicate of that package in a different version., and won't makes sense in some cases...

Use case eslint-find-rules

The package looks up rules available in ESLint that are not configured in your config.
For it to make sense for a user, it needs to check the ESLint package they installed, and not some specific version your package comes with (or latest).
So, it's a peer dependency.

Now if you want to contribute to the project, you want to have ESLint installed in node_modules so you can test your code, without doing some npm-link with a dummy project that installs ESLint.

When the user runs yarn, the system should not install peer deps and warn they're missing (this works).

So... a flag that makes yarn install peer deps if they're not already installed would kindly solve that problem.

Interesting point

  • yarn add <package> --peer installs it to node_modules and adds it to package.json
  • yarn add <other_package> after that removes the installed package from node_modules
@gaastonsr

This comment has been minimized.

Copy link

@gaastonsr gaastonsr commented Jul 6, 2017

I'm currently following @nikolakanacki model and it seems to work. I agree it can be confusing and I would prefer a yarn install --peer to install dependencies, devDependencies and peerDependencies but this works just as good to me.

@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented Jul 10, 2017

If I'm getting this right @kyleholzinger / @gaastonsr, you're not looking to install peerDependencies in development mode (cd-ed into the repo / package which has peerDependencies, fresh clone, need to develop on those peer deps) but add them to the target project once you install the package which has peer deps?

To clarify: You install eslint-find-rules which complains that you need eslint as a dependency (it's a peerDependency of eslint-find-rules), so now you want an easy way of adding those dependencies in the peer you're working on (current project which depends on eslint-find-rules)? Something like "Resolve and add as new dependencies (modify package.json and yarn.lock) best matched peer dependencies my current dependencies require"?

If this is your point it could be super useful, I thought that you were referring to auto-installing them when developing.

The feature could be introduced for more then pure convenience, for example: multiple dependencies could depend on the same package from the peer target, but require different versions of it - this feature could make the best of it by trying to resolve to a single best-matching target (if possible).

Something to think about definitely.

@gaastonsr

This comment has been minimized.

Copy link

@gaastonsr gaastonsr commented Jul 10, 2017

If this is your point it could be super useful, I thought that you were referring to auto-installing them when developing.

This is what I'm looking for. Installing peerDependencies when I'm developing a package.

@keyboard-clacker

This comment has been minimized.

Copy link

@keyboard-clacker keyboard-clacker commented Jul 10, 2017

Yeah exactly @nikolakanacki! I feel like there's a great opportunity for us to help people out with managing their peer deps.

@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented Jul 10, 2017

@gaastonsr need to add it to devDependencies then - it's as simple as that. Your package is broken for development otherwise. Once you clone the project and run yarn - everything should be installed and you should be able to run tests, etc.

Two simple and totally unrelated questions one should ask before installing said dependency in cases like this:

  1. My package depends on this package, but I expect the target project to include it since my package is just a plugin for that package: Put it in peerDependencies.
  2. I have tests that depend on this package but it is not listed in my dependencies (and should not be listed there) for whatever reason: Put it in devDependencies.

In other words: All the packages which are expected to be present during development and are not listed as a direct dependency of the package being developed should reside in devDependencies. Duplicates are not an issue - nowhere in the docs does it states that dupes are not allowed / encouraged in these cases.

@alexilyaev

This comment has been minimized.

Copy link

@alexilyaev alexilyaev commented Jul 10, 2017

@nikolakanacki When we build a plugin for a package we should depend on the installed package version by the user, if we add it as a devDependency, we'll inevitably install a different version and it will be used instead of the user's version.

Unless we defined the dependency as *, but then Yarn should be somehow deterministic and prefer the user installed package instead of ours.

Currently it's not so:

@gaastonsr

This comment has been minimized.

Copy link

@gaastonsr gaastonsr commented Jul 10, 2017

@alexilyaev I think @nikolakanacki means to install it both as a peerDependency and devDependency.

This has the problem that we need to keep both in sync. For me it works good for now but I don't think it's ideal.

@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented Jul 10, 2017

@alexilyaev when you declare a peerDependency you declare its version as well. Unless target project has the version of that peer dependency installed which also satisfies the version you defined - yarn / npm will report an error (missing peer dependency, something like that).

Non the less devDependency has nothing to do with it, it is the one getting installed when running yarn or npm install inside the source package (the one declaring a peer dependency, eg: a plugin), and it is not even consulted when the package is being used by a third party package / project (a peer).

The point is: I don't see how all this is relevant?

@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented Jul 10, 2017

I can see the pain of keeping them in sync, but you could easily write a bash / javascript / <whatever> script that would check this as a post-install step in the package.json.

The point I'm trying to make is that in no way should we break the devDependencies sentiment, or worse yet introduce "running yarn or npm install does not necessarily installs all the required dependencies of this package" concept.

On the other hand yarn introduced an even more strict policy when it comes to this, it clears up the packages not otherwise defined as dependencies or devDependencies so you don't run into issues later on.

@alexilyaev

This comment has been minimized.

Copy link

@alexilyaev alexilyaev commented Jul 10, 2017

@nikolakanacki Let's say my plugin accepts ^7.0.0 and the latest of the peer is 7.9.0 and the user defined in their package.json 7.4.0.
if I'll have ^7.0.0 in devDependencies as well, wouldn't Yarn install (for the user) both 7.9.0 and 7.4.0?

If it does, my plugin might mistakingly use the installed 7.9.0 instead of 7.4.0.

@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented Jul 10, 2017

@alexilyaev Your package will always, as any other package in any other case, use the highest available version which satisfies the "semver range" defined in your package for this peer dep.

I'd be more specific but I don't quite understand the case you've presented, could you please clarify?

@gaastonsr

This comment has been minimized.

Copy link

@gaastonsr gaastonsr commented Jul 10, 2017

It will warn you that you have a peerDependency incompatibility, your plugin expects ^7.0.0 and you have version 7.4.0. Updated: ^7.0.0 satisfies 7.4.0.

wouldn't Yarn install (for the user) both 7.9.0 and 7.4.0?

Yarn doesn't install peerDependencies for you and won't install the devDependencies of your plugin just the dependencies in dependencies.

@nikolakanacki

This comment has been minimized.

Copy link

@nikolakanacki nikolakanacki commented Jul 10, 2017

@gaastonsr you're absolutely right except that ^7.0.0 is satisfied by 7.4.0.

Peer dependencies never get installed, dev dependencies do not get installed by default if the package is not the main package. The "end-user" needs to define which peer dependencies it want's to satisfy by adding them to regular "dependencies" of the project, along with the range. It can either satisfy or not satisfy the "semver range" you require in your plugin, and the user will be notified of the latter.

Semver ranges explained by npm: https://docs.npmjs.com/misc/semver
When in doubt always check: http://jubianchi.github.io/semver-check/

@MFry

This comment has been minimized.

Copy link

@MFry MFry commented Jul 10, 2017

@nikolakanacki to be able to easily install packages peerdependencies would be great!

misogl added a commit to vacuumlabs/webpack-config-vacuumlabs that referenced this issue May 17, 2018
ncoden added a commit to ncoden/foundation-sites that referenced this issue May 22, 2018
peerDependencies is for dependencies that are exposed to (and expected to be used by) the consuming code, as opposed to "private" dependencies that are not exposed, and are only an implementation detail.

* We need `jQuery` and `motion-ui` as peerDependencies instead of dependencies because we actually expect the user to install them. We cannot simply remove them because we still need the package managers to check for versions compatibilities and warn the user if they are missing.
* We need `jQuery` and `motion-ui` as devDependencies too because we use them for tests/build/documentation and peerDependencies are not installed (even in development mode - yarnpkg/yarn#1503).

See foundation#11290
@dominikg dominikg referenced this issue Jun 13, 2018
1 of 2 tasks complete
@biels

This comment has been minimized.

Copy link

@biels biels commented Aug 21, 2018

How is it possible that we don't have this feature yet? I am new to creating npm packages, but it looks like it is part of the core workflow of developing npm packages.

@keyboard-clacker

This comment has been minimized.

Copy link

@keyboard-clacker keyboard-clacker commented Aug 21, 2018

Same @biels! I actually totally forgot I said I was gonna work on this so haven't started yet, I'll try to work on it when I can though so we can at least have people put this option in a .yarnrc and not have to worry about it all the time

@lucasfcosta

This comment has been minimized.

Copy link

@lucasfcosta lucasfcosta commented Sep 14, 2018

I think this feature is extremely important.

I can think of many use-cases, especially when it comes to library authors.

Let's say I want to develop a component library which has react and react-dom as peerDependencies (I don't want them to eventually be bundled by whoever uses it, that would duplicate those two libraries and could cause problems, which I have experienced before).

I want to test my component library with those peerDependencies installed, so I'd like to run yarn --include-peerDeps (or something like that) on CI and on my machine, but when someone runs yarn on their own package I want them to use their own react and react-dom dependencies to run their tests (doesn't matter how they do it).

I also think that since we've got modules out there that do exactly this and have plenty of downloads it already justifies making this feature native. (The old motto of "make something people want" applies here IMO)

I can't see how this could be a bad practice since it would have to be explicitly toggled through --include-peerDeps.

I'm happy to discuss and help with the implementation if needed.

@keyboard-clacker

This comment has been minimized.

Copy link

@keyboard-clacker keyboard-clacker commented Sep 14, 2018

@lucasfcosta couldn't agree more! I don't have a ton of time to work on it these days so have been trying to poke around when I can, but can't seem to get the option truthy from the command line option. Would love a helping hand though :)

@keyboard-clacker

This comment has been minimized.

Copy link

@keyboard-clacker keyboard-clacker commented Sep 14, 2018

@lucasfcosta here's my bad implementation of where I thought the option might live, I have no idea though. Was trying to follow the pattern of a couple other of the command line options, but didn't seem to work.

@RWOverdijk

This comment has been minimized.

Copy link

@RWOverdijk RWOverdijk commented Sep 18, 2018

I'm currently taking the duplication approach (devDependencies and peerDependencies) but would very much love this feature so I can stop doing that.

@eatsjobs

This comment has been minimized.

Copy link

@eatsjobs eatsjobs commented Oct 4, 2018

I need that too. in the meantime i've done a little node task

const pkg = require('./package.json');
const entries = Object.entries(pkg.peerDependencies);
const shell = require('shelljs');

let deps = ['yarn add'];
for ([dep, version] of entries) {
	deps[deps.length] = `${dep}@${version}`;
}

deps.push('--peer');
const cmd = deps.join(' ');
console.log('Installing peer deps!\n -----', cmd);
const result = shell.exec(cmd);

if (result.code !== 0) {
	shell.echo('Error: installing peer dependencies');
	shell.exit(1);
}
@biels

This comment has been minimized.

Copy link

@biels biels commented Oct 4, 2018

@nerdmax

This comment has been minimized.

Copy link

@nerdmax nerdmax commented Oct 19, 2018

I'm also taking the duplication approach as @RWOverdijk said. Love to see this feature in the future.

Btw, does anyone have a better solution so that we don't need to add one package twice(devDependencies and peerDependencies)?

misogl added a commit to vacuumlabs/webpack-config-vacuumlabs that referenced this issue Nov 9, 2018
* Add script for installing peer dependecies
See yarnpkg/yarn#1503

* Add test configuration

* Fix eslint errors and warnings

* Add workflow to CircleCI config

* Use node 10 image

* Remove `yarn` from test script
@415DomSmith

This comment has been minimized.

Copy link

@415DomSmith 415DomSmith commented Mar 6, 2019

Hello from the future. This is still an issue for package/lib developers. Duplicate deps shouldn't be the answer.

@ChrisBrownie55

This comment has been minimized.

Copy link

@ChrisBrownie55 ChrisBrownie55 commented Apr 14, 2019

I would definitely like to see this feature added. Without adding react to my package's devDependencies, I'm unable to run tests on my code.

A flag for installing the packages in the local peerDependencies object would be nice but I also don't see any downside to making installing only local peerDependencies the default behavior. And semantically it makes sense, the peer dependencies need to be there for the package to work everywhere else, why would it be any different locally?

My opinion on the usage for a flag would be the following because of its alignment with the
yarn add --peer command.

yarn --peer
# and
yarn install --peer

At the very least the flag should be introduced.

donaldshen added a commit to donaldshen/el-data-tree that referenced this issue Apr 29, 2019
将peerDependencies也加入到devDependencies中。
FYI: yarnpkg/yarn#1503
@jamstooks

This comment has been minimized.

Copy link

@jamstooks jamstooks commented Aug 15, 2019

I wonder if using separate test app is a good solution here? You could then add all your peerDependencies as dependencies of the test app. This seems to do the following:

  • keeps peerDependencies out of devDependencies in your library
  • you will be e2e testing your library, in a way... ensuring that your dist is built properly, you're exporting all your components correctly and that sort of thing
  • avoids the occasional Invalid hook call error when you forget to clear out node_modules from your package when using local dependencies, like "my-package": "file:/path/to/my-package"

If more info would be helpful for folks, I created a demo repo in an effort to model this approach and document the issue:
https://github.com/jamstooks/package-peer-dependencies

@FWirtz

This comment has been minimized.

Copy link

@FWirtz FWirtz commented Aug 18, 2019

For now, you should be able to run npx install-peerdeps <package> and the CLI then asks you whether you want to use Yarn for installing, if you have a yarn lock etc. in the folder. At least that worked for me just now.

@karlhorky

This comment has been minimized.

Copy link

@karlhorky karlhorky commented Oct 25, 2019

More discussion from Arcanis ("fail the install on missing peer deps") and Isaac ("install peer deps automatically") over here in this NPM RFC:

npm/rfcs#43

@willian

This comment has been minimized.

Copy link

@willian willian commented Oct 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.