npm install 如果 package.json 被修改
Posted
技术标签:
【中文标题】npm install 如果 package.json 被修改【英文标题】:npm install if package.json was modified 【发布时间】:2019-02-27 05:19:42 【问题描述】:TL;DR:如果您的 package.json
已被修改,有没有办法让 npm install
在运行任何 npm 脚本之前自动运行?
问题场景
您拉取或签出更新了package.json
的分支。你运行npm run my-script
。 my-script
依赖于新添加到 package.json
的包。 my-script
失败。你想知道为什么。在翻转你的桌子之前,你运行npm install
只是为了确定。 my-script
运行成功。你不需要一张新桌子。
我知道像gradle
这样的构建/任务运行工具会在运行任务之前确保您的依赖项是最新的。我一直是npm
不这样做的(次要)痛点。我偶然发现了两个我不太喜欢的解决方案。
非理想解决方案:make
您可以使用 make
并通过以下技巧利用其集成的依赖跟踪,而不是依赖 package.json
中的 npm 脚本来运行命令:
# Smart install: Only executes if package.json's
# modification date is later than node_module's
node_modules: package.json
npm install
@rm -f node_modules/.modified
@touch -m node_modules/.modified
install: node_modules
来源:https://mattandre.ws/2016/05/make-for-hipsters/
问题是你知道必须依赖 make
来运行脚本,而失去了 npm 脚本的某些优势,例如方便地引用其他脚本和并行运行脚本 (npm-run-all
)。如果他们不知道make
或在运行它时遇到问题(Windows),与其他人一起工作也会更加困难。它是 node/npm 生态系统之外的一个过时工具,而且对于这种智能安装优势而言成本太高。
非理想解决方案:Git 挂钩
另一种方法是添加post-merge
git hook。
问题是这个解决方案是存储库本地的,不能轻易共享。 npm install
只会在 git 合并时自动运行。当您以任何其他方式更改package.json
时,您仍然必须记住运行npm install
。诚然,这在实践中只是一个小问题。尽管如此,当您想要运行脚本时,完全不必考虑运行 npm install
会很好。
来源:https://davidwalsh.name/git-hook-npm-install-package-json-modified
理想的解决方案
我想以类似于以下方式定义我的package.json
:
"scripts":
"pre-run": "npm-smart-install",
"my-script": "…"
,
"dependencies":
"npm-smart-install": "1.0.0"
npm-smart-install
是一个我希望存在的假设 npm 包。 pre-run
是一个假设的 npm-scripts 生命周期钩子。当我运行npm run my-script
并且package.json
自上次运行任何脚本以来已被修改时,请在运行my-script
之前运行npm install
。
重复一遍:如果您的 package.json
已在不依赖 npm 生态系统之外的工具的情况下被修改,有没有办法让 npm install
在运行任何 npm 脚本之前自动运行?
【问题讨论】:
您自己的假设包可能并不难实现。您可以在第一次安装时生成package.json
的哈希摘要,然后在后续安装中使用它来检查文件是否更改。 This 看起来有类似的功能。
另外,为什么不在任何脚本之前运行npm install
?如果一切都存在正确的版本,那么它不会做任何事情。
这会延迟每个脚本的运行。
这听起来像是NPM's tink 希望解决的问题(尽管那是几年之后的事了)。
我的包裹快用完了。试图弄清楚我如何像在理想的解决方案场景中那样执行它。
【参考方案1】:
和其他答案一样,但我认为更简单,因为它是 package.json 中的一行 shell 脚本:
"scripts":
"install-if-needed": "[ package.json -nt node_modules ] && npm install && touch node_modules",
"my-script": "npm run install-if-needed && ..."
或者,基本等价:
"scripts":
"install-if-needed": "[ package.json -nt node_modules ] && npm install && touch node_modules",
"premy-script": "npm run install-if-needed",
"my-script": "..."
对于每个需要它的脚本,您必须内联 npm run install-if-needed
或拥有一个 pre...
脚本——我不知道有什么其他方法可以让它在多个其他脚本之前运行。
解释:install-if-needed
检查package.json
和node_modules
的修改时间。如果node_modules
更新,它什么也不做;否则它运行npm install
。最后的touch node_modules
是必要的,因为npm install
本身可能会更改 package.json 的修改时间(例如,如果它正在更正 package.json 中的空白)。
【讨论】:
node_modules 的最后修改时间不会像 npm/yarn lockfile 的哈希一样可靠:/【参考方案2】:您可以创建一个自定义脚本来运行您的智能安装。
smart-install.sh 文件
#!/usr/bin/env bash
changedFiles="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
checkForChangedFiles()
echo "$changedFiles" | grep --quiet "$1" && eval "$2"
packageJsonHasChanged()
echo "Changes to package.json detected, installing updates"
npm i
checkForChangedFiles package.json packageJsonHasChanged
然后,如果您有哈士奇犬,您可以将其添加到结帐后挂钩或您喜欢的任何挂钩中。如果你没有 husky,你也可以直接将它添加到本质上做同样事情的脚本中。
.huskyrc 文件
"hooks":
"post-checkout": "npm run smart-install"
package.json 文件
"scripts":
...
"smart-install": "bash ./bin/smart-install.sh",
无论哪种方式,最好创建一个 npm 脚本来运行 smart-install
【讨论】:
类似yarnhook:github.com/frontsideair/yarnhook【参考方案3】:好的,我已经完成了包裹。 Here 是。您可以完全按照您在理想场景中指定的方式使用它。只需 npm install install-changed
并将其添加到自定义脚本中,例如您的示例中的 pre-run
。它应该弄清楚它是否需要npm install
,如果需要就这样做。
"scripts":
"pre-run": "install-changed",
"my-script": "…"
,
您也可以通过编程方式执行此操作,但我认为您不需要它。
let installChanged = require('install-changed')
let isModified = installChanged.watchPackage()
上面的函数做同样的事情,此外它还返回一个布尔值,你可能会发现它很有用。
【讨论】:
干得好!我只是希望 npm 有一个集成的“预运行”钩子。就像现在一样,我必须写"my-script": "npm run prerun && …"
或"premy-script": "install-changed", "my-script": "…"
。
而不是packagehash.txt
,它应该使用git历史记录中package.json
的当前版本
install-changed
有一个 fork,叫做package-changed
,它基本上是一样的,但更灵活,允许你在 package.json deps/devDeps 变化时运行任何命令。然后我分叉了这个分支并将其命名为lockfile-changed
,因为它只是创建了yarn.lock
内容的哈希值。这都是关于纱线的。我建议使用package-changed
,除非你真的希望它基于 yarn.lock+use yarn。如果你使用我的包,它可能有错误。我还没有完全测试过。以上是关于npm install 如果 package.json 被修改的主要内容,如果未能解决你的问题,请参考以下文章
npm install 如果 package.json 被修改
[Vue] npm install 如果安装node-sass失败,可以用如下方法解决
[Vue] npm install 如果安装node-sass失败,可以用如下方法解决