简体   繁体   English

如何使用peerDependencies解决NPM中的依赖地狱

[英]How to resolve dependency hell in NPM with peerDependencies

Setup: 设定:

Given the following points 鉴于以下几点

  • my_library makes extensive runtime use of jquery . my_library在运行时大量使用jquery
  • in my_library the jquery required via npm is ^3.3.1 by default (because of security fixes in it). my_library中 ,通过npm所需的jquery默认为^3.3.1 (因为其中存在安全修复程序)。 However it is compatible also with jquery >=2.2.0 (but is not specified in package.json , yet) 但是它也与jquery> = 2.2.0兼容(但尚未在package.json指定)
  • the my_library is used in a custom_project via npm . my_library通过npmcustom_project中使用。
  • the custom_project requires also outer_library , that is using different & conflicting jquery versions (eg let's say jquery 1.7.3 ). custom_project还需要external_library ,即使用不同且冲突的jquery版本(例如jquery 1.7.3 )。
  • the custom_project_2 instead just requires my_library in dependencies . 相反, custom_project_2仅需要my_library dependencies

Problems: 问题:

  • installing custom_project will provoke duplicate dependencies, messing up jquery for one of the two libraries. 安装custom_project会引起重复的依赖关系,使两个库之一的jquery混乱。
  • the jquery version in my_library dependencies specifies a suggested version (in order to avoid critical vulnerabilities) but doesn't say anything about which jquery minimum version is compatible with my_library my_library dependenciesjquery版本指定了建议的版本(以避免严重漏洞),但是没有说明哪个jquery最低版本与my_library兼容

Eventual solution: 最终解决方案:

To avoid jquery dependency duplication (1.7.3 for outer_library and 3.3.1 for my_library ) I could move my jquery ^3.3.1 from dependencies to devDependencies , so I'll get the 3.3.1 on development while it won't be installed on production ( npm install --only=prod ) and just jquery 1.7.3 will be installed. 为了避免jQuery的依赖重复(1.7.3 outer_library和3.3.1 my_library)我可以从移动我的jQuery 3.3.1 ^ dependenciesdevDependencies ,所以我会得到发展的同时,3.3.1将不能安装在生产中( npm install --only=prod ),将仅安装jquery 1.7.3

But this: 但是这个:

  • doesn't guarantees that my_library will get a compatible jquery version, so my_library could easily break. 不能保证my_library将获得兼容的jquery版本,因此my_library可能会轻易中断。
    • adding jquery@>=2.2.0 inside my_library peerDependencies will at least raise a WARN asking to resolve the conflict manually installing a specific version in custom_project (even though probably it can't be solved). my_library peerDependencies添加jquery@>=2.2.0至少会引发一个WARN,要求您解决此冲突,以便在custom_project中手动安装特定版本(即使可能无法解决)。
  • feels wrong to me since jquery is a runtime dependency and shouldn't go into devDependencies (with unit-testing tools, etc.). 我感觉不对,因为jquery是运行时dependency ,不应进入devDependencies (使用单元测试工具等)。 In fact jquery won't be installed in the custom_project_2 , when installing on production (so my_library will break) 实际上,在生产环境中安装时,不会将jquery安装在custom_project_2中 (因此my_library将中断)

Questions 问题

  1. How can I manage to satisfy both use cases of dependency by my_library ? 如何通过my_library满足两个用例的依赖?

  2. (A) In case the outer_library would require a jquery compatible with my peerDependencies definition ( >=2.0.0 ), would I STILL need to install jquery manually? (A)如果external_library需要一个与我的peerDependencies定义( >=2.0.0 )兼容的jquery ,我是否peerDependencies需要手动安装jquery Or npm will resolve a common version? 还是npm将解决一个通用版本?

  3. (B) Are there cases where peerDependencies doesn't complain and doesn't require to install anything manually? (B)在某些情况下, peerDependencies不抱怨并且不需要手动安装任何东西吗? (as long as semvers are honoured?) (只要遵守荣誉?)

  4. (A) Does it make sense to put a dependency like jquery (high probability of conflicts) either inside peerDependencies (with an as loose as possible semver ) and inside dependencies with the recommended version? (A)应当把它放在一个依赖像jQuery(高冲突概率) 或者内部peerDependencies (用尽可能semver松散) 内部dependencies与推荐的版本?

  5. (B) Would that work correctly in every setup and with NPM version <3 (peerDependencies automatically installed) and >=3 (manual installation needed)? (B)在NPM版本<3 (自动安装peerDependencies)和>=3 (需要手动安装)的所有设置中该方法都能正常工作吗?

Appreciated if you can answer even to a part of the questions 🙃 感谢您是否可以回答部分问题🙃

Is it safe to assume the dependency of my_library on jquery is a peer dependency? 可以安全地假设my_library对jquery的依赖关系是对等依赖关系吗? And that you are on the development team of my_library? 您是my_library开发团队的成员吗?

If so, the best solution might be to change my_library's peer dependency on jquery into a regular dependency. 如果是这样,最好的解决方案可能是将my_library对jquery的对等依赖关系更改为常规依赖关系。 If I understand this article correctly, only peer dependencies can generate conflicts between packages, regular packages get installed into subdirectories so my_library get's it's own version of jquery installed, seperate from outer_library. 如果我对本文的理解正确,那么只有对等方依赖项才能在软件包之间产生冲突,常规软件包会安装到子目录中,因此my_library就是它自己安装的jquery版本,与external_library分开。

It might just be impossible to convert a peer dependency into a regular dependency however. 但是,可能无法将对等依赖项转换为常规依赖项。 https://medium.com/@jacob.h.page/common-npm-mistakes-51bf8989079f https://medium.com/@jacob.h.page/common-npm-mistakes-51bf8989079f

Is your module a plugin for some library or framework? 您的模块是某个库或框架的插件吗? Then that library/framework is a peer dependency. 那么那个库/框架是对等的依赖。 The consuming application is responsible for selecting and integrating a set of mutually-compatible plugins; 消费应用程序负责选择和集成一组相互兼容的插件。 the plugins themselves should not introduce said framework directly, but should instead specify a maximally-inclusive version range to make the job of integration as easy as possible. 插件本身不应该直接引入上述框架,而应该指定一个最大范围的版本范围,以使集成工作尽可能容易。

Your other option would be to wait for outer_library to release a new version that IS compatible with the latest jquery. 您的另一个选择是等待outer_library发布与最新的jQuery兼容的新版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM