【问题标题】:Get version in npm preversion script在 npm preversion 脚本中获取版本
【发布时间】:2020-12-01 07:37:39
【问题描述】:

我正在尝试获取我在 npm preversion 脚本中创建的版本。

如:

{
    "scripts": {
        "preversion": "echo $version"
    }        
}

但我找不到要写什么来代替$version

我想在我做npm version <something> 时得到我正在创建的版本。例如,如果我做npm version 1.0.1,我想得到1.0.1。但是,如果我在版本1.0.0 时执行npm version minor,我想获得1.1.0

【问题讨论】:

  • 我不确定您要的是什么。你能澄清一下吗?你想得到什么版本:"version" package.json 或其他的条目?根据我的理解,@NaorLevi 的回答似乎是正确的,但似乎不是您要找的。所以请解释一下

标签: node.js npm npm-scripts


【解决方案1】:

重新定义您的preversion 脚本如下:

"scripts": {
  "preversion": "echo $npm_package_version"
}

说明:

这将访问package.json varsnpm_package_version 变量是 npm 创建的众多环境变量之一。

*nix 平台上,npm 默认使用 sh 运行 package.json 脚本。因此,您使用 $ 前缀引用 npm 脚本中的环境变量,即 $npm_package_version

但是,在 Windows 上,npm 默认使用 cmd 运行脚本。在这种情况下,您需要使用 %...% 语法在 npm 脚本中引用环境变量。例如:

"preversion": "echo %npm_package_version%"

如果需要跨平台支持,您可以通过使用 cross-var 来避免语法差异,即 $ 前缀 v 的 %...%。在这种情况下,您需要重新定义您的 preversion 脚本,如下所示:

"scripts": {
  "preversion": "cross-var echo $npm_package_version"
}

提示:如果你 cd 到你的项目目录并运行 npm run env 它会列出所有 npm 创建的带有 npm_* 前缀的环境变量。

【讨论】:

  • 看来npm 实际上并没有设置环境变量,而只是进行了某种内部插值。我在 Windows 上的 git bash 中执行了上述操作,当我使用“$”时它失败了,但可以使用“%”(如图所示)。
  • @Allen - 在 Windows 上 npm 使用 cmd.exe 作为运行 npm 脚本的默认 shell。如果您运行npm config get script-shell 来获取当前的script-shell 设置,它可能会返回cmd
  • 啊,所以你说它不会在当前 shell 中执行脚本,而是使用其配置的 script-shell 来运行脚本,这就是它的行为方式与我描述的方式相同的原因。我只是在寻找有关更改script-shell 的参考资料,但找不到太多。我可以更改该设置以改用 git bash 吗?
  • 我刚试了一下,好像还不错。
  • @Allen - 是的,就是这样。请参阅this post,了解如何配置 npm 以在运行 npm 脚本时使用 git bash shell。但是请注意,您的软件包的大多数使用者将使用默认 shell,即 cmd.exe(在 Windows 上)或 sh(在*nix)。对于跨平台的可移植性,请考虑使用上面我的回答中建议的 cross-var 包 - 这样您就可以使用 $ 前缀语法来引用 var。
【解决方案2】:

来自docs

具体执行顺序如下:

[...]

  1. 运行 preversion 脚本。这些脚本可以访问 package.json 中的旧版本。

因此,不可能在preversion 脚本中轻松获取未来版本,因为它是在版本实际更改之前运行的。您可以想出一些 hacky 解决方案,例如:

"preversion": "mkdir ../ver && node -e \"const p = require('./package.json'); delete p.scripts.preversion; require('fs').writeFileSync('../ver/package.json', JSON.stringify(p), 'utf8')\" && cd ../ver && npm version minor && node -e \"console.log('new version is gonna be',require('./package.json').version);\" && cd -"

这基本上将 package.json 文件复制到另一个目录,运行 npm version minor 并打印新版本。问题是硬编码的npm version minor,当你运行npm version 1.0.1时,它不会给你正确的结果,并且没有办法获得触发这个脚本的相同命令(至少我不知道有什么办法)并在它完成之前再次运行它。

我不知道您的要求,但我会使用versionpostversion 脚本以便轻松获得新版本。或者您可以创建一些自定义脚本,它执行相同但在所有脚本启动之前生成新版本并且可以访问新版本。

【讨论】:

  • 确实,文档说 preversion 脚本可以访问旧版本。但是,鉴于此package.json: { "name": "test", "version": "1.0.0", "scripts": { "preversion": "cross-var echo \"preversion $npm_package_version\"", "version": "cross-var echo \"version $npm_package_version\"", "postversion": "cross-var echo \"postversion $npm_package_version\"" }, "devDependencies": { "cross-var": "^ 1.1.0" } } 运行npm version patch 时,所有三个echo 命令都显示1.0.1
  • @Blade1336 这种行为在 NPM 7 中似乎有所改变; preversion 现在报告 1.0.0。
【解决方案3】:

如果您正在寻找以前的版本,这将有所帮助:

{
    "scripts": {
        "preversion": "node -p 'JSON.parse(fs.readFileSync(`package.json`)).version'"
    }        
}

其他方式只会让您获得新版本。

【讨论】:

    猜你喜欢
    • 2019-10-25
    • 2020-09-22
    • 1970-01-01
    • 2022-08-14
    • 2014-02-14
    • 1970-01-01
    • 2019-09-06
    • 2018-07-14
    • 2019-12-04
    相关资源
    最近更新 更多