TL; DR:如果您的npm install
被修改,有没有办法让package.json
在运行任何npm脚本之前自动运行?
您拉出或签出更新了package.json
的分支。您运行npm run my-script
。 my-script
取决于新添加到package.json
的软件包。 my-script
失败。你想知道为什么。为确保安全,在翻转办公桌之前,请运行npm install
。 my-script
成功运行。您不需要新的办公桌。
我知道gradle
之类的构建/任务运行器工具在运行任务之前请确保您的依赖项是最新的。 npm
并没有为我带来一个(小)痛苦。我偶然发现了两个我不喜欢的解决方案。
使用package.json
而不是依靠make
中的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),与他人合作也将变得更加困难。它是节点/ npm生态系统之外的一种古老工具,而且仅凭此智能安装优势就太昂贵了。
另一种方法是添加一个post-merge
git钩子。
问题在于此解决方案是存储库本地的,无法轻松共享。 npm install
仅在git merge上自动运行。当您以其他任何方式更改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
被修改后,请在运行npm install
之前运行my-script
。
要重复一遍:如果您的npm install
在不依赖npm生态系统之外的工具的情况下进行了修改,是否有办法让package.json
在运行任何npm脚本之前自动运行?
答案 0 :(得分:2)
好的,我已经完成了包装。 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()
上面的函数做完全相同的事情,此外,它还返回一个布尔值,您可能会发现它有用。
答案 1 :(得分:1)
您可以创建将运行智能安装的自定义脚本。
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
然后,如果您有沙哑的话,可以将其添加到结帐后挂钩或您喜欢的任何挂钩中。如果您没有沙哑的狗狗,也可以将其直接添加到实质上执行相同操作的脚本中。
.huskyrc文件
{
"hooks": {
"post-checkout": "npm run smart-install"
}
}
package.json文件
"scripts": {
...
"smart-install": "bash ./bin/smart-install.sh",
}
无论哪种方法,创建一个运行smart-install
的npm脚本都是一个好主意
答案 2 :(得分:0)
与其他答案类似,但我认为更简单,因为它是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...
脚本-我不知道有什么其他方法可以让它在多个其他脚本之前运行。 / p>
说明:install-if-needed
检查package.json
和node_modules
的修改时间。如果node_modules
是较新的,则不执行任何操作。否则,它将运行npm install
。最后一个touch node_modules
是必要的,因为npm install
本身可能会更改package.json的修改时间(例如,如果它要更正package.json中的空白)。