[英]npm install if package.json was modified
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
不这样做的(次要)痛点。 我偶然发现了两个我不太喜欢的解决方案。
无需依赖package.json
中的 npm 脚本来运行您使用make
的命令,并通过以下技巧利用其集成的依赖跟踪:
# 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 生态系统之外的一个古老的工具,而且对于这种智能安装优势来说太昂贵了。
另一种方法是添加一个post-merge
git 钩子。
问题是这个解决方案是存储库本地的,不能轻易共享。 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 脚本之前自动运行?
好的,我已经完成了包裹。 在这里。 您可以完全按照您在理想场景中指定的方式使用它。 只需npm install install-changed
并将其添加到自定义脚本中,例如您的示例中的pre-run
。 它应该弄清楚它是否需要npm install
并在需要时这样做。
{
"scripts": {
"pre-run": "install-changed",
"my-script": "…"
},
您也可以以编程方式执行此操作,但我认为您不需要它。
let installChanged = require('install-changed')
let isModified = installChanged.watchPackage()
上面的函数做同样的事情,此外它还返回一个布尔值,你可能会发现它很有用。
您可以创建一个自定义脚本来运行您的智能安装。
智能安装.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"
}
}
包.json 文件
"scripts": {
...
"smart-install": "bash ./bin/smart-install.sh",
}
无论哪种方式,创建一个 npm 脚本来运行smart-install
都是一个好主意
像其他答案一样,但我认为更简单,因为它是 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 中的空白)。
一种简单的解决方案是使用 git diff 和 grep
git diff --name-only HEAD HEAD~1 | grep package.json && npm install
此命令首先检查最新提交和最后一次提交之间的差异,从中列出最新更改的文件。之后使用 grep 在该列表中查找“package.json”。如果在列表中找到它,它将运行“npm install”或者它不会。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.