简体   繁体   English

纱线:使用依赖的yarn.lock

[英]Yarn: use yarn.lock of dependencies

I use yarn to install packages directly from the companies' GitLab: 我使用yarn直接从公司的GitLab安装包:

yarn add git+ssh://<user>@<host>:<repo>

For first-level dependencies, I use yarn --pure-lockfile to reconstruct my node_modules according to the yarn.lock . 对于第一级依赖项,我使用yarn --pure-lockfile node_modules根据yarn.lock重建我的yarn.lock

However, for second level dependencies yarn seems to always install the latest version. 但是,对于二级依赖,yarn似乎总是安装最新版本。

So let's say I depend on A which is tested with a specific version of B . 所以,假设我依赖于使用特定版本B测试的A In A's package.json I don't specify the version, but it is contained in the yarn.lock . 在A的package.json我没有指定版本,但它包含在yarn.lock

When I now install package A yarn will get the latest version of B despite the entry in A/yarn.lock 当我现在安装包装A纱线将获得最新版本的B尽管在A/yarn.lock

I know that I might resolve this by passing a specific version in A/package.json (at least I think). 我知道我可以通过在A/package.json传递特定版本来解决这个问题(至少我认为)。

But is there an option to tell yarn to look at the yarn.lock of dependencies? 但有没有选择告诉纱线看看依赖的yarn.lock

TLDR: TLDR:

When you install dependencies in your application, only your own yarn.lock file is respected. 在应用程序中安装依赖项时,只会考虑您自己的yarn.lock文件。 Lockfiles within your dependencies will be ignored. 您的依赖项中的锁定文件将被忽略。 Reference 参考


Let's get some things cleared first: 让我们先清除一些东西:

  1. --pure-lockfile is same as normal yarn install except that it won't generate a yarn.lock file or update one if present. --pure-lockfile与普通纱线安装相同,只是它不会生成yarn.lock文件或更新一个(如果存在)。
  2. Yarn always reads from the yarn.lock by default for resolving dependencies while installing unless supplied with --no-lockfile . 除非提供--no-lockfile yarn.lock ,否则Yarn总是默认从yarn.lock读取以解析依赖关系。 So, there is no need to tell it to read from yarn.lock . 因此,没有必要告诉它yarn.lock读取。

What is yarn.lock used for? 什么是yarn.lock用于?

yarn.lock is used for resolving what version should be fetched given the semver version of a module in package.json . yarn.lock用于解决什么version应该给出的是获取semver version在模块package.json It is not used to determine what semver version should a module be resolved to. 用于确定模块应解析为什么样的semver version That is simply not its use-case . 这根本不是它的用例

As mentioned in yarn DOCS : In order to get consistent installs across machines, Yarn needs more information than the dependencies you configure in your package json.. Yarn needs to store exactly which versions of each dependency were installed . 正如纱线DOCS中所提到的:为了在机器之间获得一致的安装,Yarn需要的信息比您在软件包json中配置的依赖项更多.Yarn需要准确存储每个依赖项的安装版本

To do this Yarn uses a yarn.lock file in the root of your project. 为此,Yarn在项目的根目录中使用yarn.lock文件。

So, for resolving semver version of a dependency, yarn always depends on package.json . 因此,为了解析依赖关系的semver version ,yarn总是依赖于package.json For a given semver version , yarn checks the yarn.lock file to see what version should it fetch. 对于给定的semver version ,yarn检查yarn.lock文件以查看它应该获取的version This is what makes yarn Deterministic (Same tecknique is used by npm which uses npm-shrinkwrap.json ). 这就是使得纱线确定性的原因npm使用npm-shrinkwrap.json使用相同npm-shrinkwrap.json )。

Example : Semver Versions like ^1.2.4 can resolve to any version number which is >= 1.2.3 and < 2.0.0 . 示例^1.2.4类的Semver版本可以解析为>= 1.2.3 and < 2.0.0任何版本号。 Without yarn, npm would install 1.2.4 in one machine but 1.9.9 in some other machine, depending on the latest version present at the time of install. 如果没有纱线,npm将在一台机器上安装1.2.4 ,在其他机器上1.9.9 ,具体取决于安装时的最新版本。 This is the problem that yarn solves using yarn.lock . 这是纱线使用yarn.lock解决的问题。

The semver version is determined by the package.json file. semver versionpackage.json文件确定。 The yarn.lock file is only a lookup for which version and commit hash to install for the given semver version number. yarn.lock文件只是查找为给定的semver version号安装哪个版本提交哈希

How does yarn resolve version of a module given its semver version? 鉴于其semver版本,yarn如何解析模块的版本?

Suppose currently our yarn.lock file looks like this: 假设我们的yarn.lock文件当前如下所示:

bluebird@2.9.6:
  version "2.9.6"
  resolved "https://<...>/bluebird-2.9.6.tgz#1fc3a6b1685267dc121b5ec89b32ce069d81ab7d"

bluebird@^2.9.30:
  version "2.11.0"
  resolved "https://<...>/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
...
myModule@5.1.0:
  version "5.1.0"
  resolved "https://<...>/moduleA-5.1.0.tgz#ce97130858add59d616ee80675383b0c127290a0"
  dependencies:
    bluebird "^1.0.0"
  1. If package.json has bluebird: "^2.9.30" , yarn looks for an entry bluebird@^2.9.30 in the lockfile. 如果package.json有bluebird: "^2.9.30" ,则yarn会在bluebird: "^2.9.30"查找条目bluebird@^2.9.30 It is present and hence is resolved to version=2.11.0 . 它存在,因此被解析为version=2.11.0
  2. If package.json has bluebird: "^2.9.0" , yarn looks for an entry bluebird@^2.9.0 in the lockfile. 如果package.json有bluebird: "^2.9.0" ,则yarn会在lockfile中查找条目bluebird@^2.9.0 It is not present. 它不存在。 Suppose the latest stable version which satisfies semver criteria is 2.13.0 , then yarn adds an entry for bluebird@^2.9.0 , resolved to 2.13.0 . 假设满足semver标准的最新稳定版本为2.13.0 ,则yarn为bluebird@^2.9.0添加一个条目,解析为2.13.0 While resolving version for a given semver version of bluebird, it does not matter what entry is present for bluebird in moduleA's dependencies in the lockfile. 在解析给定的蓝鸟semver version时,对于lockfile中moduleA的依赖项中bluebird的条目无关紧要。

Semver Version is not affected by what entries are present in the dependencies map for a module in yarn.lock file. Semver Version 不会受到什么条目出现在地图的依赖在一个模块yarn.lock文件。

So, if package.json has bluebird: "" , yarn looks for an entry bluebird@ in the lockfile but is unable to find it. 因此,如果package.json有bluebird: "" ,则yarn会在lockfile中查找条目bluebird@但无法找到它。 Hence, it resolves bluebird: "" to the latest version, suppose 3.5.0 . 因此,它解决了bluebird: ""到最新版本,假设为3.5.0 Now, yarn will add an entry for bluebird@ resolved to 3.5.0 . 现在,纱线将为bluebird@ 3.5.0添加一个条目为3.5.0

bluebird@:
  version "3.5.0"
  resolved "https://<...>/bluebird-3.5.0.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"

Form now on whenever yarn encounters {bluebird: ""} , it will find an entry for bluebird@ in the lockfile and hence will always resolve it to 3.5.0 . 现在只要纱线遇到{bluebird: ""} ,它就会在锁定文件中找到bluebird@的条目,因此总是会将其解析为3.5.0

Solution to your problem 解决您的问题

To resolve B: "" to version say 1.0.0 , you need to have an entry for B@ in yarn.lock resolved to 1.0.0 . 要解决B: ""到版本说1.0.0 ,你需要在yarn.lock B@yarn.lock解析为1.0.0 Once, yarn.lock has an entry for B@ , all the successive installs will always fetch version 1.0.0 for B="" . 一旦, yarn.lock有一个B@条目,所有连续安装将始终获取版本1.0.0B=""

Following are the steps you need to take to accomplish the same: 以下是完成相同操作所需的步骤:

Approach 1 (Recommended) 方法1 (推荐)

If you want B to resolve to latest version: 如果您希望B解析为最新版本:

  1. Add B:"" in A's package.json 在A的package.json中添加B:""
  2. Run yarn install . 运行yarn install This will add an entry for B@ resolved to latest version. 这将为B@ resolve添加最新版本的条目。
  3. Push yarn.lock file. yarn.lock文件。
  4. Form now on, whoever runs yarn install will get the same version. 从现在开始,无论谁运行yarn install都会获得相同的版本。

Approach 2 方法2

If you want B to have an older version: ( Highly Not Recommended ) 如果你想B有旧版本:( 强烈不推荐

  1. Add B: 1.0.0 in A's package.json. 在A的package.json中添加B: 1.0.0
  2. Run yarn install . 运行yarn install This will add an entry B@1.0.0 in the lockfile. 这将在B@1.0.0中添加一个条目B@1.0.0
  3. Add B@ alongside B@1.0.0 in yarn.lock. B@1.0.0中添加B@和B@1.0.0。 B@, B@1.0.0: ...
  4. Change B's version to "" in A's package.json. 在A的package.json中将B的版本更改为""
  5. Push yarn.lock file. yarn.lock文件。
  6. Form now on, whoever runs yarn install will get the B's version as 1.0.0 . 从现在开始,无论谁运行yarn install将获得B版本1.0.0

This approach is highly dangerous as you can break something easily. 这种方法非常危险,因为您可以轻松破坏某些东西。 Your yarn.lock file should always be managed by yarn . 您的yarn.lock文件应始终由yarn管理

Approach 3 (Recommended) 方法3 (推荐)

If you want B to stay at 1.0.0 如果你想让B保持在1.0.0

  1. Fix B's version to 1.0.0 in A's package.json. 在A的package.json中将B的版本修复为1.0.0
  2. Run yarn install . 运行yarn install This will add an entry B@1.0.0 in the lockfile. 这将在B@1.0.0中添加一个条目B@1.0.0
  3. Push yarn.lock file 推yarn.lock文件
  4. Form now on, whoever runs yarn install will get the B's version as 1.0.0 . 从现在开始,无论谁运行yarn install将获得B版本1.0.0

Edit: Using the yarn.lock file present in the dependencies 编辑:使用依赖项中存在的yarn.lock文件

If you check this doc :, they have clearly mentioned that yarn will use only the top level yarn.lock file and ignore the lock files present in the dependencies. 如果你查看这个doc :,他们已经清楚地提到纱线将只使用顶级 yarn.lock文件并忽略依赖项中存在的锁文件。

There is currently no way of locking down second level dependencies using yarn.lock present in them. 目前无法使用其中存在的yarn.lock锁定第二级依赖项。 I don't see any need for it. 我认为没有必要。 In fact the creators of yarn explain here why that is the case. 事实上,纱线的创造者在这里解释为什么会这样。 The reasons being: 原因是:

  1. The versions to be installed for second level dependencies can be captured well by the top-level yarn.lock file, as I have explained above. 如上所述,顶层yarn.lock文件可以很好地捕获为二级依赖项安装的版本。
  2. You would never be able to update the versions of sub-dependencies in your own application when using them directly because they would be locked by other yarn.lock files. 直接使用它们时,您永远无法更新自己应用程序中的子依赖项版本,因为它们会被其他yarn.lock文件锁定。 You can verify this point by my explanation of how yarn resolves dependencies. 您可以通过我对纱线如何解析依赖关系的解释来验证这一点。
  3. Yarn would never be able to fold (de-duplicate) dependencies so that compatible version ranges only install a single version. Yarn永远无法折叠(去重复)依赖项,因此兼容的版本范围只能安装单个版本。

Also, as in your use-case, if A has a dependency B which works only with version 1.0.0 , A's package.json should have version mentioned for B as 1.0.0 and not “”. 此外,如在您的用例中,如果A具有仅与版本1.0.0一起使用的依赖关系B,则A的package.json应该具有针对B提到的版本1.0.0而不是“”。 You can always fix your top-level yarn.lock to add an entry for B@ resolved to 1.0.0 but it is not recommended to manually fix a yarn.lock file as I have mentioned above. 您可以随时解决您的顶级yarn.lock添加一个条目B@解析到1.0.0 ,但不建议手动固定yarn.lock文件作为我所提到的。

Hope this helped! 希望这有帮助! Please ping me in the comments for any doubts. 如有任何疑问,请在评论中告诉我。

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

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