gpt4 book ai didi

npm - 在npm安装单个软件包后运行脚本(如postinstall)?

转载 作者:行者123 更新时间:2023-12-04 21:07:26 31 4
gpt4 key购买 nike

我开始玩Snowpack。它与Webpack采取了不同的方法,即在安装各个软件包后立即捆绑它们。

“问题”是,当我安装软件包时,我必须先运行npm install --save my-package,然后必须手动将其与npx snowpack打包在一起。 Snowpack docs提到我可以包含一个prepare脚本,该脚本在运行snowpack之后将对所有内容进行npm install,但不适用于单个软件包,仅适用于npm install中所有依赖项的通用package.json 。据我所知,npm docs中提到的所有npm挂钩都是这种情况。

每当安装单个软件包时,有什么方法可以自动运行脚本?我能想到的唯一方法是覆盖安装脚本并向其中添加一些内容。在GitHub或其他地方有任何示例吗?

更新:为澄清起见,每次安装带有npx snowpack的新软件包时,我都希望运行--save,但最好不要安装--save-dev或不安装--save。这对于任何软件包都不会有什么不同。这将特定于某个回购/项目,而不是系统上的全局项目。

仅运行snowpack后仅运行npm install是不够的,因为您可以钩入postinstallrelease。另外,我想确保在我的项目上工作的开发人员可以像往常一样使用npm install --save newdep,然后snowpack将运行。我不想要求开发人员使用自定义的命名脚本。

最佳答案

简短答案:不幸的是,npm不提供任何内置功能来满足您的要求。
诸如postinstall之类的生命周期挂钩/脚本仅在运行通用npm install命令时被调用,而在项目开发阶段中有人在运行npm install --save <pkg_name>时则不被调用。

解决方法:考虑通过从本质上在外壳程序级别覆盖npm install --save命令来定制npm复合命令的逻辑。
以下解决方案(尽管是Bash解决方案)描述了如何针对特定项目实现这种自定义逻辑。但是,此解决方案取决于以下条件:

运行npm install --save复合命令时,从事您的项目的开发人员必须将其shell设置为Bash
在您的项目上工作的开发人员将需要自定义其Bash startup files,即~/.bashrc,可能还有~/.bash_profile
项目目录(即您希望自定义逻辑对其生效的项目目录)必须包含自定义.bashrc文件。


重击解决方案:
以下三个步骤是配置项目和操作系统所必需的,以便开发人员运行npm install --save <pkg_name>(或其变体)时,随后将调用npx snowpack命令。
注意:第二点和第三点(以下)是开发人员自定义Bash启动文件所需执行的任务。

项目特定的.bashrc文件:
首先,在项目目录的根目录中创建以下“特定于项目的” .bashrc文件,即,将其保存在与项目package.json文件所在的目录相同的级别:
/some/path/to/my-project/.bashrc

npm() {

local name_badge="\x1b[37;40mpostinstall\x1b[0m"

array_includes() {
local word=$1
shift
for el in "$@"; do [[ "$el" == "$word" ]] && return 0; done
}

log_warn_message() {
local cmd_name=$1 warn_badge warn_mssg
warn_badge="\x1b[30;43mWARN!\x1b[0m"
warn_mssg="${cmd_name} command not found. Cannot run npx snowpack."
echo -e "\n${name_badge} ${warn_badge} ${warn_mssg}" >&2
}

log_run_message() {
echo -e "\n${name_badge} Running pseudo postinstall hook."
}


if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then

# 1. Run the given `npm install --save ...` command.
command npm "$@"

# 2. Check whether the `npx` command exists globally.
command -v npx >/dev/null 2>&1 || {
log_warn_message npx
return 1
}

log_run_message

# 3. Run the pseudo "postinstall" command.
command npx snowpack

else
# Run all other `npm` commands as per normal.
command npm "$@"
fi
}

注意:为了更好地了解此文件的功能,请参阅下面的“说明”部分。

~/.bashrc文件:
为了使自定义逻辑(即上述 npm文件中的 .bashrc函数)生效,必须将Bash配置为读取上述“特定于项目的” .bashrc文件。要进行配置,请将以下代码行添加到 ~/.bashrc
PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'

注意:为了更好地理解此代码行的功能,请参阅下面的“说明”部分。

~/.bash_profile文件:
通常,您的 ~/.bash_profile包含以下代码行以加载 ~/.bashrc文件(或其某些变体):
if [ -f ~/.bashrc ]; then . ~/.bashrc; fi

如果不存在,则必须将其添加到 ~/.bash_profile



附加信息。
设置/配置助手:
考虑您的开发人员按照上述步骤二和三,使用以下两个命令来帮助配置其Bash启动文件。

对于第二步,运行以下命令:
echo $'\n'"PROMPT_COMMAND='if [[ \"\$bashrc\" != \"\$PWD\" && \"\$PWD\" != \"\$HOME\" && -e .bashrc ]]; then bashrc=\"\$PWD\"; . .bashrc; fi'" >> ~/.bashrc

这会将 PROMPT_COMMAND=...代码行添加到现有的 ~/.bashrc文件中,或者如果尚不存在,则创建一个新的代码行:

对于第三步,运行以下命令以在 ~/.bash_profile中添加用于加载 ~/.bashrc文件所需的代码行:
echo $'\n'"if [ -f ~/.bashrc ]; then . ~/.bashrc; fi" >> ~/.bash_profile



我的外壳是否配置为Bash?
要检查外壳是否配置为Bash,可以创建一个新会话,即创建一个新的Terminal窗口并运行:
echo $0

如果显示 -bash,则说明它正在使用Bash。
如何将我的外壳配置为Bash?
如果 echo $0不打印 -bash,则需要更改外壳。要将其更改为Bash,请运行:
chsh -s /bin/bash

注意:您需要创建一个新会话以使此更改生效。

说明

项目特定的 .bashrc文件:
.bashrc文件包含名为 npmshell function。该函数的主体包含重写默认的 npm install|i --save命令所必需的逻辑。

if语句中指定的条件,即读取的部分;
if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then
...
fi

本质上是读取 $* special parameter来检查传递给 npm函数的参数是否以这两者开头。 install ,或者是速记等效项 i ,以及是否也传递了 --save选项/参数。
为了检查 --save参数的存在,我们将 $@特殊参数传递给 array_includes函数。我们对此参数的处理方式不同,因为 --save选项的位置在复合命令中可能有所不同。例如,用户可以通过运行此软件包来安装软件包;
# Example showing `--save` option at the end
npm install <pkg_name> --save

或这个(或其他变体):
# Example showing `--save` option in the middle
npm i --save <pkg_name>


当满足 if语句中指定的条件(即它们为 true)时,我们将在其正文中执行以下任务:

通过如下行直接运行给定的 npm install --save ...命令:
command npm "$@"


通过以下内容检查 npx命令是否全局存在:
command -v npx >/dev/null 2>&1 || {
log_warn_message npx
return 1
}

如果 npx命令不可用(全局),则警告用户无法运行 npx snowpack命令,并警告该功能 return早期退出,且退出状态为 1
注意:我在此检查中的逻辑假定您将全局安装 npx。但是,如果要在项目中本地安装 npm,则需要更改此逻辑。也许通过检查 ./node_modules/.bin/npx是否存在。或者,您可能确信 npx命令将始终存在,因此得出结论,此检查是不必要的。

如果 npx命令是全局存在的,则我们运行伪的“ postinstall”命令,即
command npx snowpack




当不满足 if语句中指定的条件(即它们为 false)时,用户实际上正在运行任何其他非 npm install --save <pkg_name>的npm命令。因此,在 else分支中,我们按原样运行命令:
command npm "$@"




〜/ .bashrc文件:
在《 Bash参考手册》的 5.2 Bash Variables部分中, PROMPT_COMMAND变量描述如下:

PROMPT_COMMAND
如果设置,则该值将解释为在打印每个主提示( $PS1)之前执行的命令。

因此,这行代码(再次出现):
PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'

加载“特定于项目”的 .bashrc(如果存在的话),该 npm依次使用 npm函数覆盖 npm install --save命令。这实际上是为特定项目覆盖覆盖 @Cyrus复合命令的机制。
有关更多说明,请参见 this answer

关于npm - 在npm安装单个软件包后运行脚本(如postinstall)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59934610/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com