【问题标题】:How to know the version of currently installed package from yarn.lock如何从 yarn.lock 知道当前安装包的版本
【发布时间】:2020-06-12 16:58:08
【问题描述】:

我正在编写一个内部工具,它比较项目中安装的版本,只允许通过某些版本。为此,我必须检查在 yarn.lock 文件中解析的版本,因为 package.json 文件有一个 semver 范围,而不是特定版本,并且它不会告诉你依赖项的依赖关系。

我尝试使用yarn list 命令,但它也会打印 semver 范围并且很难解析(即使使用--json 选项)。 所以yarn.lock 似乎是唯一的方法。我知道yarn.lock 可能有同一个包的不同版本,在这种情况下,我只想要安装在其中的版本。node_nodules(必须只是其中之一)。我不知道如何解析锁定文件。

我能想到的另一种方法实际上是进入node_modules 文件夹并检查包的package.json 中的版本。

以上选项对我来说都不干净。有什么方法可以让我尽可能轻松、干净地知道特定包的已解决版本(前提是我知道包的名称并且知道它已安装)?

更新
我实际上想要已安装包的所有版本(即使它们在依赖关系树中非常深)。

【问题讨论】:

  • 不太确定是否有帮助,但因为您知道包的名称。 npm info [package_name] version 可以帮助检索软件包版本。
  • @VaritJPatel 它不返回已安装的软件包版本。它只是从 npm 注册表中获取信息
  • 可能最好的方法是使用require.resolve查找实际将要包含的节点模块的位置,然后读取package.jsonnodejs.org/api/…
  • 这不可能/不容易。

标签: javascript node.js typescript yarnpkg


【解决方案1】:

我发现yarn why是找出当前安装的软件包版本的最佳方法(感谢我的一位同事向我指出)。这就是我的测试代码在 JavaScript 中的样子。

const { spawnSync } = require('child_process');
const packageName = 'micromatch';
const whyBuffer = spawnSync('yarn', ['why', packageName]);
const grepBuffer = spawnSync('grep', ['Found'], { input: whyBuffer.stdout });
const outputArray = grepBuffer.stdout.toString().split('\n');
console.log(outputArray); // ['info \r=> Found "micromatch@3.1.10"',    'info \r=> Found "fast-glob#micromatch@4.0.2"', ''  ]
const parsedOutputArray = outputArray.filter(output => output.length > 0).map((output) => output.split('@')[1].replace('"', ''))
console.log(parsedOutputArray); // [ '3.1.10', '4.0.2' ]

【讨论】:

  • 答案对我有用,但可以通过处理范围包的情况来改进(当包名称以@ 开头时):output.split('@')[1] 这里使用数组的最后一个元素,而不是第二个。跨度>
【解决方案2】:

既然您知道包的名称,请执行以下操作:

yarn list --pattern <package_name>

上述命令将为您提供任何深度的软件包的所有已安装版本。例如,我在不同深度安装了不同版本的camelcase 库。运行命令:yarn list --pattern "camelcase",输出如下:

yarn list v1.22.5
├─ camelcase@6.2.0
└─ yargs-parser@13.1.2
   └─ camelcase@5.3.1

【讨论】:

  • 我猜模式值需要是一个正则表达式字符串。我检查了react,它列出了所有以他们的名字做出反应的包。
【解决方案3】:

npm list --depth=0yarn why &lt;each package&gt; 快 1000 倍。 它还告诉您无关的依赖关系、未满足的对等部门等,但输出非常干净 - 仍然比 yarn why 干净。

【讨论】:

  • 你怎么能确定它快了 1000 倍?有基准吗?此外,我只对深度 0 的 deps 不感兴趣。此外,我不想知道每个包裹。我只想知道是否安装了给定的软件包,如果是,安装的版本是什么。解析整个列表似乎比只使用 yarn why 慢。
  • 另外一点是我使用 yarn 作为包管理器,而不是 npm。在不使用 package-lock.json 的情况下使用 npm list 时,我收到很多缺少部门的错误。
【解决方案4】:

对于程序化使用,我喜欢yarn list

yarn list --pattern lodash --depth=0 --json --non-interactive --no-progress | jq -r '.data.trees[].name'
lodash@4.17.21
lodash.defaults@4.2.0
lodash.flatten@4.4.0
lodash.isarguments@3.1.0
lodash.memoize@3.0.4

为了更好的编程使用:https://www.npmjs.com/package/@yarnpkg/lockfile

【讨论】:

  • 已经有了相同解决方案的答案。怎么样更好?此外,如果我只想了解 lodash 包,我必须为其添加另一个过滤器。
【解决方案5】:

由于 yarn list 尚未针对较新版本的 Yarn 实现,并且 yarn why 可能有点难以解析,所以 yarn info 是另一种选择。它输出在 yarn.lock 中解析的版本。

$ yarn info sass -A
└─ sass@npm:1.41.0
   ├─ Version: 1.41.0
   │
   ├─ Exported Binaries
   │  └─ sass
   │
   └─ Dependencies
      └─ chokidar@npm:>=3.0.0 <4.0.0 → npm:3.5.2

或者,只获取名称和版本:

$ yarn info sass -A --name-only
└─ sass@npm:1.41.0

如果只获取版本,您可以使用--json 标志以更机器可读的格式输出,然后使用jq 解析它:

$ yarn info sass -A --json | jq ".children.Version"
"1.41.0"

【讨论】:

    猜你喜欢
    • 2019-12-09
    • 2020-08-10
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    相关资源
    最近更新 更多