peerDeps + deps VS peerDeps + devDeps (Best Practice?)


(Igor Pellegrini) #1

What are npm-experienced people thinking about mixing peedDependencies with dependencies or devDependencies?

Info

peerDependencies should have an as loose as possible semver, and ensures that a warning is raised when these deps are not satisfied by the project. It will not install the deps automatically (from NPM3 on), and the user has to install them manually.

In a context of a library_foo that is dependent on jQuery, I want the less cumbersome setup for the users requiring the library in their projects.

  • peerDependencies will always raise a warn, but not solve the problem. Action by the user is always required.
  • if I put jquery also in dependencies then it will be installed automatically (and a good semver would push for having the latest security updates), the peerDependencies will be satisfied, no warning will be shown to the user (nice :+1:), and this latter won’t have to perform any additional action (good! :ok_hand:), except in case a valid version cannot be resolved and a specific one, preferred by the user, needs to be installed in the project (fair enough :woman_shrugging:).
  • if I put jquery in depDependencies I get the additional advantage that it won’t be installed on production (npm install --only=prod), so in case another dependency of the project requires a different version of jquery then just that will be installed. In case this different version is not compatible with the library_foo, then the entry in peerDependencies will still warn the user that *he needs to fix manually.

Now…

  • putting in devDeps, in case the project requires exclusively library_foo, then no jquery version will be installed on production (and break the app). User will always have to install manually (if he reads the warning and/or is experienced).
  • putting in devDeps feels wrong, since library_foo strictly depends on jquery at runtime; shouldn’t that stay in dependencies?
  • putting in devDeps then peerDependencies will require the correct installation and warn in other case, but will not ensure a correct installation after running npm install --only=prod. And still jquery is not a devDependency)
  • putting in dependencies feels correct the most, but it could lead to duplicate dependencies (breaking at runtime, when trying to instantiate jquery), without warning the user (since all the deps are satisfied)

Actual Questions…

  • What is the best choice? (given that the user should be annoyed or required intervention just when something needs to be actually solved)
  • What is the best compromise between ambiguously/wrongly putting jquery in devDependencies and risking to get a duplicated dependency?
  • What is the most compatible choice? (that works on NPM 2 & >3)
  • Is getting duplicates so bad? There is an article about dealing with NPM3 peerDependencies behaviour changes that says it is not. I am not sure about the different cases that provoke duplication, so am not sure how to react to them.

Would be nice to have some clarity and define the best practice in this case. Documentation is a little outdated and doesn’t mention cases where peedDeps are mixed with other deps directives.


(Igor Pellegrini) #2

Any idea or suggestion?
Your experience?


(Christopher J Brody) #3

Sounds like a judgment call depending on the relative merits and pitfalls between the two proposed alternatives. For JQuery I would personally favor a peerDep for the following reasons:

  • number of existing libraries and frameworks that use JQuery
  • easier for the end user to select which version of JQuery or JQuery replacement alternative to use
  • ability to update JQuery in one place

(Igor Pellegrini) #4

Thanks for your answer @brodybits. Yes, I am trying to get to a best practice for the peerDeps case (since many people/blogs/devs have different, sometimes confusing, opinions).

I agree, peerDependencies is the main fixed requirement. I am never gonna remove that.

Just, after moving the dep solely in there, old (NPM > 2) users relying on automatic installation of the library_foo deps will suddenly have additional (WARN and) requirements to satisfy on their project (installing jQuery manually); even if:

  • they just have library_foo as single dep (so no possibility of jQuery duplication/conflict)
  • they never had to (decide and) install anything manually, until now
  • it is actually possible to satisfy the dependencies automatically, without conflicting versions, in (assumption) most cases

My main question mark is actually about what to use additionally to peerDependencies:

  • dependencies, so that the use case above will be painless for the user updating library_foo (but still with risk of duplication, especially on NPM2)
  • devDependencies, used for automatic install while developing; but not installing anymore automatically for the use case above that depends exclusively on library_foo (also, jQuery is not only a developing dependency)

?


Or are dependencies and peerDependencies intended to be mutually exclusive?

(I can’t find an answer to this anywhere on the net or the NPM docs or the Yarn docs)


(Christopher J Brody) #5

In your case I would put it (JQuery) in peerDepencies and devDependencies, assuming there is actually a reason such as the existence of a working test suite for adding it to devDependencies. I would see the following mutually exclusive choices for each possible dependency:

  • add the dependency to dependencies
  • add the item to peerDependencies, devDependencies, or both

I hope this answers your question. I am still not an expert at npm internals, just giving the answers that make the most sense to me given my experience to date. I remain hopeful that a npm expert will be able to confirm. You may be able to get better answers from Stack Overflow.

I am also still not an expert in the existing npm documentation but would have to agree with you that it should be improved in this respect. I cannot promise when I would have time to better verify the actual behavior and contribute documentation. If you have a chance to take a better look at the code and improve the documentation I am sure the maintainers and community members would be really happy.


(Igor Pellegrini) #6

Thanks for your answer @brodybits!

Yes, I would improve the documentation, but I feel still too noob about npm for being able to write something completely correct. My verbosity also wouldn’t help much in being clear :sweat_smile: But who knows, maybe in some months I’ll feel better about it!

Regarding my dependencies question…

Yes, I agree about your view on the mutually exclusive options.
What confused me was to have something just in devDependencies but not in dependencies, and felt wrong for a runtime dependency; but, yes, peedDependencies deputises for dependencies, even if with a looser approach: throwing a warn and delegating the user for installing it (kind of IoC). At least in NPM3 (that is another point of trying to choose the right place: retro-compatibility).

Am not yet satisfied with the manual install of the peer-dependency to be needed even when library_foo is the only dependency. That would have been one advantage of putting jQuery inside dependencies. But as I understand it could also lead to dependency duplicates (and break at runtime).

Dunno… maybe a postInstall script (in the library?) could take care of installing jQuery, if the dependency tree doesn’t have it. But also am not sure whether an operation like this would be more a responsibility of the package manager and would be a mistake trying to take care of it myself :thinking:

Still thinking about it…


(system) #7

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.