【问题标题】:Best practice for upgrading npm `prepublish` script for npm@>=4为 npm@>=4 升级 npm `prepublish` 脚本的最佳实践
【发布时间】:2017-05-18 02:47:54
【问题描述】:

我从my sample project's 根文件夹运行npm install 以使用package.json 中的脚本构建它。

构建需要当前在 prepublish 脚本中的一些转译步骤,但 npm 版本 4 显示警告说即将发生重大变化,这让我相信 新的 em> prepare 构建事件脚本更具前瞻性。

C:\code\antlr4ts-json>npm install
npm WARN prepublish-on-install As of npm@5, `prepublish` scripts will run only for `npm publish`.
npm WARN prepublish-on-install (In npm@4 and previous versions, it also runs for `npm install`.)
npm WARN prepublish-on-install See the deprecation note in `npm help scripts` for more information.
...

不幸的是,简单地将脚本从 prepublish 移动到 prepare 会破坏向后兼容性:如果有人使用 npm@3 运行 npm installprepare 中的构建步骤将被忽略。

升级构建时脚本的最佳做法是什么?理想情况下,我想更新我的 package.json,以便 npm install 适用于任何 npm@>=3 ,但也可以生成一个明确的错误消息,表明在使用 npm@3 运行 npm install 时需要 npm@>=4 是完全可以接受的.

Bakground:我试过包括

"engines": { "npm":  ">=4.0.0" },

感谢@toomuchdesign(和其他人),我明白为什么这不能满足我的要求; engines 仅检查我的包何时安装作为依赖项,而不是有人从源代码构建它。这是有道理的。

我跟踪了这​​个计划更改的背景,一直到npm issue #10074,这解释了为什么需要进行重大更改。但是我仍然不清楚如何更好地处理过渡。

【问题讨论】:

  • 我已经更新了这个问题,以便更清楚地说明我在这里寻找最佳实践。我还更新了它以指向一个更简单的示例项目github.com/BurtHarris/antlr4ts-json
  • 更正示例项目 URL:github.com/BurtHarris/antlr4ts-json
  • 注意:我已经将我的解决方案提交到示例项目中。
  • 如果您对答案投了反对票,请留言说明原因...
  • 这似乎是一个非常大的问题,建议的解决方案看起来可行,但我希望有一个“官方”的 npm 建议。

标签: npm npm-install


【解决方案1】:

我使用check-node-version 找到了更好的解决方案;该软件包有一个命令行界面,使其易于用于此目的。以下是我建议的最佳实践步骤:

  1. 使用npm install -D check-node-version@1 添加开发依赖项,
  2. 将现有的prepublish 脚本重命名为prepare
  3. 添加替换 prepublish 脚​​本以处理向后兼容性,并建议升级 npm(见下文。)

我的 package.json 现在看起来像这样:

"scripts": {
    "prepare": "npm run antlr4 && tsc",
    "prepublish": "check-node-version --npm \">=4\" || npm run prepare",
    "antlr4": "rimraf gen && antlr4ts Json.g4 -o gen -visitor",
    ...
},
"devDependencies": {
    "check-node-version": "^1.1.2",
    ...

采用这种方法:

  • npm install 始终运行prepare 脚本,即使安装了npm@3。如果安装了npm@5(未经测试),这应该可以正常工作。

  • npm@3 上甚至还有一条关于升级npm 的有用信息,但是由于脚本使用|| npm run prepare 来模拟更高版本的行为,因此脚本在出错后继续运行。

  • 如果我以后想对npm@4 进行硬依赖,删除|| npm run prepare 部分会导致脚本在npm@3 上运行时停止。

这是使用npm@3 构建的样子:

C:\code\antlr4ts-json>npm i

> antlr4ts-json@1.0.6-alpha prepublish C:\code\antlr4ts-json
> check-node-version --npm ">=4" || npm run prepare

node: v6.9.1
npm: v3.10.10
Error: Wanted npm version ">=4" (>=4.0.0)
To install npm, run `npm install -g npm@>=4`

> antlr4ts-json@1.0.6-alpha prepare C:\code\antlr4ts-json
> npm run antlr4 && tsc

【讨论】:

  • 也许更好的是我发现check-node-version 已经包含一个可以检查 npm 版本的 CLI...
  • 但是,版本检查和prepare 脚本不会抑制警告。最好也摆脱它们。
  • 是的。不过,这将在 npm 中发生变化。
【解决方案2】:

NPM docs 声明 engines 字段仅在您的包作为依赖项安装时才会抛出错误:

除非用户设置了 engine-strict 配置标志,否则 [engines] 字段是建议性的,仅当您的包作为依赖项安装时才会产生警告。

作为项目的开发者/维护者,您不应该看到来自您的engines 字段的任何警报。

由于您只需要在运行npm install 时编译文件,因此您可以简单地使用postinstall 挂钩。

还请注意,prepublish 会一直存在,它只会在publish 钩子之前触发,从而改变其在npm@5 上的行为。

【讨论】:

  • 好的,这就解释了为什么使用 engines 字段不起作用,但我仍在寻找最佳实践,当有人运行时需要 npm > v4 npm install 在我的项目文件夹中。
  • 谢谢。我编辑了问题描述以澄清我正在寻找解决方案而不仅仅是解释。
  • 感谢您的更新,但底部的npm scripts doc 非常清楚:不要使用install。我认为这也适用于postinstall,这些步骤在最终用户机器上执行步骤的唯一原因取决于我的包(不是我的场景。)但它仍然建议使用prepublish,而不需要获得有关警告的任何更新上面列出的。
  • 我想我可以写一个脚本/模块来解决这个问题,我只是很惊讶我找不到已经发布的东西来解决这个问题。
  • 我已经编写了自己的解决方案,我会将其标记为已接受。感谢@toomuchdesign 的帮助。
猜你喜欢
  • 2017-11-06
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 2017-01-13
相关资源
最近更新 更多