如何从相对版本中获取确切的最新 npm 版本? [英] How can I get the exact latest npm version from a relative version?

查看:62
本文介绍了如何从相对版本中获取确切的最新 npm 版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够获得与相对语义版本匹配的 npm 的最新发布版本.

例如,我想运行类似:

npm -v 6.12.x

然后返回匹配的确切最新版本:

=>6.12.1

我已经浏览了一些可用的文档和命令,或者认为使用 npm 可以做到这一点,但我没有看到任何可以在不安装另一个全局依赖项的情况下工作的内容.

解决方案

简短回答: npm 没有提供完全满足您要求的内置功能.<​​/p>

但是,npm 确实提供了 npm-view 命令.它的文档说明如下:

<块引用>

如果提供了版本范围,则将为包的每个匹配版本打印数据.这将显示每个匹配的 yui3 版本需要哪个 jsdom 版本:

npm view yui3@'>0.5.4' dependencies.jsdom.

下面给出的两个解决方案演示了如何解析/操作 npm view 命令的输出以满足您的要求(无需安装另一个全局依赖项).

<小时>

解决方案 A:*仅限 Nix 平台(Linux/MacOS...)

因此,可以借助一些额外的 Bash 实用程序来解析输出来满足您的要求.

考虑运行以下复合命令:

npm 查看 npm@'6.12.x' 版本 |尾-n 1 |cut -d "'" -f2

说明

下面对上述复合命令中的组成部分进行说明:

  1. npm 查看 npm@'6.12.x' 版本

    这部分利用npm view命令返回给定范围内的所有版本,即6.12.x.

    独立运行这些部分将在您的控制台上打印以下内容:

    <块引用>

    npm@6.12.0 '6.12.0'npm@6.12.1 '6.12.1'

  2. <代码>|tail -n 1

    然后使用管道将先前显示的结果传送到 tail-n 1 选项,以便只打印最后一行.

    运行:

    npm 查看 npm@'6.12.x' 版本 |尾-n 1

    印刷品:

    <块引用>

    npm@6.12.1 '6.12.1'

  3. <代码>|cut -d "'" -f2

    然后使用管道将先前显示的结果传送到 cut-d 选项并指定单引号作为分隔符.-f2 部分然后选择第二项.

    运行完整的复合命令:

    npm 查看 npm@'6.12.x' 版本 |尾-n 1 |cut -d "'" -f2

    打印你想要的结果:

    <块引用>

    6.12.1

Semver 波浪号 (~) 和插入符号 (^) 范围.

您还可以使用上述复合命令指定波浪号或插入符范围.

示例:

  • 指定波浪号范围:

    npm 查看 npm@'~4.0.0' 版本 |尾-n 1 |cut -d "'" -f2^^^^^^

    打印:

    <块引用>

    4.0.5

  • 指定插入符号范围:

    npm 查看 npm@'^4.0.0' 版本 |尾-n 1 |cut -d "'" -f2^^^^^^

    打印:

    <块引用>

    4.6.1

简化用法:

如果您打算经常在 *nix 上运行该命令,那么我建议:

  1. 运行以下复合命令:

    echo $'\n'"npmv() { npm view \"npm@\${1}\" version | tail -n 1 | cut -d \"'\" -f2; }">>~/.bash_profile

    这将添加一个 shell 函数.bash_profile 文件的内容,即它会添加一个新行,内容如下:

    <块引用>

    npmv() { npm 查看 "npm@${1}" 版本 |尾-n 1 |cut -d "'" -f2;}

  2. 然后当您创建一个新会话(即创建新窗口或重新启动终端)时,以后您只需运行:

    npmv 6.12.x

    它简洁,更类似于您问题中给出的示例命令.

注意:如果你已经有名为 npmv 的 npm 包 全局安装在您的系统上,然后为 shell 函数/命令选择不同的名称以避免任何冲突.

<小时>

解决方案 B:跨平台(Windows/Linux/macOS...)

如果您使用的是 Windows,或者想要一个跨平台的解决方案(即在 Windows、Linux 和 macOS 上成功运行的解决方案...),您需要利用 nodejs 来实现您的要求.

考虑运行以下复合命令:

node -e "var res = require('child_process').execSync('npm view npm@"\"6.12.x\"" version', {encoding: 'utf-8'}).split('\n').filter(Boolean); if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } console.log(res.replace(/[']/g, '')); }"

是的,我同意它与解决方案 A 相比有些冗长 :)

说明

下面对上述复合命令中的组成部分进行说明:

  1. node -e "..."

    我们调用 node 和 nodejs 命令行选项 -e 用于评估给定的内联 JavaScript.

  2. var res = require('child_process').execSync('npm view npm@"\"6.12.x\"" version', {encoding: 'utf-8'})

    给定 node.js 脚本 (JavaScript) 的这一部分按照 解决方案 A 执行相同的 npm view 命令,即 npm view npm@"\"6.12.x\"" 版本,使用execSync().

  3. .split('\n').filter(Boolean);

    npm view 命令的结果使用字符串的 split() 方法 - 基本上结果的每一行都由换行符 \ 分割n 使每一行输出成为数组中的一个元素.

    .filter(Boolean) 部分从 Array 中删除由 npm view 命令打印的附加尾随空行产生的空元素.

  4. if (res.length) { if (res.length === 1) { res = res[0];} else { res = res.pop().split(' ')[1];} ... }

    这里我们使用了一些条件if..else 语句以确保我们从数组中获得所需的项.

  5. console.log(res.replace(/[']/g, ''));

    最后我们将结果记录到控制台并使用 replace() 方法删除包含 semver 值的单引号 (').

Semver 波浪号 (~) 和插入符号 (^) 范围.

根据解决方案 A,您还可以使用上述复合命令指定波浪号或插入符范围.

示例:

  • 指定波浪号范围:

    node -e "var res = require('child_process').execSync('npm view npm@"\"~4.0.0\"" version', {encoding: 'utf-8'}).split('\n').filter(Boolean); if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } console.log(res.replace(/[']/g, '')); }"^^^^^^

    印刷品:

    <块引用>

    4.0.5

  • 指定插入符号范围:

    node -e "var res = require('child_process').execSync('npm view npm@"\"^4.0.0\"" version', {encoding: 'utf-8'}).split('\n').filter(Boolean); if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } console.log(res.replace(/[']/g, '')); }"^^^^^^

    印刷品:

    <块引用>

    4.6.1

I want to be able to get the latest released version of npm that matches a relative semantic version.

For example, I would like to run something like:

npm -v 6.12.x

then return the exact latest version that matches:

=> 6.12.1

I have explored some of the docs and the commands available or think this is possible with npm, but I haven't seen anything that works without installing another global dependency.

解决方案

Short answer: npm does not provide a built-in feature to meet your requirement exactly.

However, npm does provide the npm-view command. It's documentation states the following:

If a version range is provided, then data will be printed for every matching version of the package. This will show which version of jsdom was required by each matching version of yui3:

npm view yui3@'>0.5.4' dependencies.jsdom.

The two solutions given below demonstrate how the output of the npm view command can be parsed/manipulated to meet your requirement (without having to install another global dependency).


Solution A: *Nix platforms only (Linux/MacOS...)

Therefore, it's possible to achieve your requirement with the help of some additional Bash utilities to parse the output.

Consider running the following compound command:

npm view npm@'6.12.x' version | tail -n 1 | cut -d "'" -f2

Explanation

The following provides an explanation of the constituent parts in the aforementioned compound command:

  1. npm view npm@'6.12.x' version

    This part utilizes the npm view command to return all versions in the given range, i.e. 6.12.x.

    Running these parts standalone will print the following to your console:

    npm@6.12.0 '6.12.0'
    npm@6.12.1 '6.12.1'
    

  2. | tail -n 1

    The previously shown result is then piped to tail using the -n 1 option so that only the last line is printed.

    Running:

    npm view npm@'6.12.x' version | tail -n 1
    

    prints:

    npm@6.12.1 '6.12.1'

  3. | cut -d "'" -f2

    The previously shown result is then piped to cut using the -d option and specifying a single quote as the delimiter. The -f2 part then selects the second item.

    Running the full compound command:

    npm view npm@'6.12.x' version | tail -n 1 | cut -d "'" -f2
    

    prints your desired result:

    6.12.1

Semver tilde (~) and caret (^) ranges.

You can also specify tilde or caret ranges with the aforementioned compound command.

Examples:

  • Specifying a tilde range:

    npm view npm@'~4.0.0' version | tail -n 1 | cut -d "'" -f2
                  ^^^^^^
    

    prints:

    4.0.5

  • Specifying a caret range:

    npm view npm@'^4.0.0' version | tail -n 1 | cut -d "'" -f2
                  ^^^^^^
    

    prints:

    4.6.1

Simplified Usage:

If you intend to run the command often on *nix then I suggest:

  1. Running the following compound command:

    echo $'\n'"npmv() { npm view \"npm@\${1}\" version | tail -n 1 | cut -d \"'\" -f2; }" >> ~/.bash_profile
    

    This will add a shell function to the content of your .bash_profile file, i.e. it will add a new line that reads:

    npmv() { npm view "npm@${1}" version | tail -n 1 | cut -d "'" -f2; }

  2. Then when you create a new session (i.e. create new window, or relaunch terminal), in the future you can simply run:

    npmv 6.12.x
    

    It's terse and more akin to the example command given in your question.

Note: If you already have the npm package called npmv installed globally on your system then choose a different name for the shell function/command to avoid any conflict.


Solution B: Cross Platform (Windows/Linux/macOS...)

If you're using Windows, or are wanting a cross-platform solution, (i.e. one that runs successfully on Windows, Linux, and macOS...), you'll need to utilize nodejs to achieve your requirement.

Consider running the following compound command:

node -e "var res = require('child_process').execSync('npm view npm@"\"6.12.x\"" version', {encoding: 'utf-8'}).split('\n').filter(Boolean); if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } console.log(res.replace(/[']/g, '')); }"

Yes, I agree it's somewhat verbose compared to Solution A :)

Explanation

The following provides an explanation of the constituent parts in the aforementioned compound command:

  1. node -e "..."

    We invoke node and the nodejs command line option -e is utilized to evaluate the given inline JavaScript.

  2. var res = require('child_process').execSync('npm view npm@"\"6.12.x\"" version', {encoding: 'utf-8'})

    This part of the given node.js script (JavaScript) shells-out the the same npm view command as per Solution A, i.e. npm view npm@"\"6.12.x\"" version, using execSync().

  3. .split('\n').filter(Boolean);

    The result of the npm view command is converted from a String to an Array using the String's split() method - essentially each line of the result is split by the newline character \n so that each line of output becomes an element in a Array.

    The .filter(Boolean) part removes empty elements from the Array that are produced by the additional trailing empty lines that the npm view command prints.

  4. if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } ... }

    Here we utilize some conditional if..else statements to ensure we obtain the desired item from the Array.

  5. console.log(res.replace(/[']/g, ''));

    Finally we log the result to console and use the replace() method to remove the single quotes (') that encase the semver value.

Semver tilde (~) and caret (^) ranges.

As per Solution A, you can also specify tilde or caret ranges with the aforementioned compound command.

Examples:

  • Specifying a tilde range:

    node -e "var res = require('child_process').execSync('npm view npm@"\"~4.0.0\"" version', {encoding: 'utf-8'}).split('\n').filter(Boolean); if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } console.log(res.replace(/[']/g, '')); }"
                                                                          ^^^^^^
    

    prints:

    4.0.5

  • Specifying a caret range:

    node -e "var res = require('child_process').execSync('npm view npm@"\"^4.0.0\"" version', {encoding: 'utf-8'}).split('\n').filter(Boolean); if (res.length) { if (res.length === 1) { res = res[0]; } else { res = res.pop().split(' ')[1]; } console.log(res.replace(/[']/g, '')); }"
                                                                          ^^^^^^
    

    prints:

    4.6.1

这篇关于如何从相对版本中获取确切的最新 npm 版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆