运行 npm 安装单个包后的脚本(如安装后)?
Run a script (like postinstall) after npm installing a single package?
我开始玩 Snowpack。它采用与 Webpack 不同的方法,在安装后立即捆绑单个包。
"issue" 是,当我安装一个包时,我必须先 运行 npm install --save my-package
然后我必须用 npx snowpack
手动打包它。 Snowpack docs mention that I can include a prepare
script that would snowpack
everything after running npm install
but that doesn't apply to individual packages, just on a generic npm install
of all dependencies in my package.json
. As far as I can tell, this is the case for all npm hooks mentioned in the npm docs.
有什么方法可以在我安装单个软件包时自动 运行 脚本?我能想到的唯一方法是覆盖安装脚本并向其中添加一些内容。 GitHub 或其他地方有这样的例子吗?
更新: 为了澄清起见,我想 运行 npx snowpack
每次安装带有 --save
的新软件包时,但最好不带 --save-dev
或不带 --save
。这对于任何包都不会有所不同。这将特定于某个 repo/project,在我的系统上不是全局的。
仅仅 运行 宁 npm install
之后 运行 snowpack
是不够的,就像挂钩到 postinstall
或 release
.此外,我想确保从事我的项目的开发人员可以像往常一样使用 npm install --save newdep
,然后 snowpack
将 运行。我不想要求开发人员使用自定义 named 脚本。
我认为最好的办法是创建一个执行所需操作的新脚本。您的 package.json 中的以下内容:
{
"scripts": {
"snowpack-install" : "npm install --save && npx snowpack"
}
}
更正
您实际上可以在 package.json 中使用 postinstall option。安装后将 运行 "AFTER the package is installed"。这看起来像下面这样:
{
"scripts": {
"postinstall" : "npx snowpack"
}
}
简短回答:很遗憾,npm 不提供任何内置功能来满足您的要求。
生命周期 hooks/scripts 例如 postinstall
are invoked only when running the generic npm install
命令,而不是在项目开发阶段有人 运行s npm install --save <pkg_name>
时。
解决方法: 考虑通过实质上覆盖 shell 级别的 npm
命令来自定义 npm install --save
复合命令的逻辑。
尽管是 Bash 解决方案,但以下解决方案描述了如何为特定项目实现此自定义逻辑。但是,此解决方案取决于以下条件:
- 当 运行 使用
npm install --save
复合命令时,从事您项目的开发人员必须将 shell 设置为 Bash。
- 从事您的项目的开发人员将需要自定义他们的 Bash startup files,即
~/.bashrc
并且可能 ~/.bash_profile
。
- 项目目录,即您希望自定义逻辑生效的项目目录,必须包含自定义
.bashrc
文件。
Bash 解法:
以下三个步骤是配置您的项目和操作系统所必需的,因此当开发人员 运行s 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=
shift
for el in "$@"; do [[ "$el" == "$word" ]] && return 0; done
}
log_warn_message() {
local cmd_name= 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
文件:
要使自定义逻辑,即上述.bashrc
文件中的npm
函数生效,需要配置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
。
附加信息。
Setup/Configuration 帮手:
考虑您的开发人员使用以下两个命令来帮助配置他们的 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
我的shell配置成Bash了吗?
要检查 shell 是否配置为 Bash 您可以创建一个新会话,即创建一个新终端 window 和 运行:
echo [=15=]
如果它打印 -bash
那么它正在使用 Bash.
如何将 shell 配置为 Bash?
如果 echo [=54=]
不打印 -bash
,那么您需要更改 shell。将其更改为 Bash 运行:
chsh -s /bin/bash
注意:您需要创建一个新会话才能使此更改生效。
说明
项目具体.bashrc
文件:
此 .bashrc
文件包含一个名为 npm
的 shell function。此函数的主体包含覆盖默认 npm install|i --save
命令所需的逻辑。
if
语句中指定的条件,即读到的部分;
if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then
...
fi
本质上是读取 $*
special parameter 以检查传递给 npm
函数的参数是否以其中之一开头; install
,或者是 shorthand 等价的 i
,以及 --save
option/argument 是否也通过了。
为了检查 --save
参数是否存在,我们将 $@
特殊参数传递给 array_includes
函数。我们以不同方式处理此参数,因为 --save
选项在复合命令中的位置可能不同。例如,用户可以通过 运行ning this;
安装一个包
# 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
命令全局存在,那么我们 运行 伪“安装后”命令,即
command npx snowpack
当 if
语句中指定的条件不满足时,即它们是 false
,用户本质上是 运行ning 任何其他 npm 命令那不是 npm install --save <pkg_name>
。因此,在 else
分支中,我们 运行 按原样执行命令:
command npm "$@"
~/.bashrc 文件:
Bash参考手册5.2 Bash Variables部分PROMPT_COMMAND
变量描述如下:
PROMPT_COMMAND
If set, the value is interpreted as a command to execute before the printing of each primary prompt ($PS1
).
因此,这行代码(再次出现):
PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'
加载“项目特定”.bashrc
(如果存在的话),它又用 npm
函数覆盖 npm
命令。这本质上是为特定项目提供覆盖 npm install --save
复合命令的机制。
请参阅 @Cyrus
的 this answer 以获得进一步的解释。
使用较新版本的 Snowpack (>=2),您可以 运行 snowpack dev
并且它会监视您的 npm_modules
文件夹以寻找要构建的新模块。
我开始玩 Snowpack。它采用与 Webpack 不同的方法,在安装后立即捆绑单个包。
"issue" 是,当我安装一个包时,我必须先 运行 npm install --save my-package
然后我必须用 npx snowpack
手动打包它。 Snowpack docs mention that I can include a prepare
script that would snowpack
everything after running npm install
but that doesn't apply to individual packages, just on a generic npm install
of all dependencies in my package.json
. As far as I can tell, this is the case for all npm hooks mentioned in the npm docs.
有什么方法可以在我安装单个软件包时自动 运行 脚本?我能想到的唯一方法是覆盖安装脚本并向其中添加一些内容。 GitHub 或其他地方有这样的例子吗?
更新: 为了澄清起见,我想 运行 npx snowpack
每次安装带有 --save
的新软件包时,但最好不带 --save-dev
或不带 --save
。这对于任何包都不会有所不同。这将特定于某个 repo/project,在我的系统上不是全局的。
仅仅 运行 宁 npm install
之后 运行 snowpack
是不够的,就像挂钩到 postinstall
或 release
.此外,我想确保从事我的项目的开发人员可以像往常一样使用 npm install --save newdep
,然后 snowpack
将 运行。我不想要求开发人员使用自定义 named 脚本。
我认为最好的办法是创建一个执行所需操作的新脚本。您的 package.json 中的以下内容:
{
"scripts": {
"snowpack-install" : "npm install --save && npx snowpack"
}
}
更正
您实际上可以在 package.json 中使用 postinstall option。安装后将 运行 "AFTER the package is installed"。这看起来像下面这样:
{
"scripts": {
"postinstall" : "npx snowpack"
}
}
简短回答:很遗憾,npm 不提供任何内置功能来满足您的要求。
生命周期 hooks/scripts 例如 postinstall
are invoked only when running the generic npm install
命令,而不是在项目开发阶段有人 运行s npm install --save <pkg_name>
时。
解决方法: 考虑通过实质上覆盖 shell 级别的 npm
命令来自定义 npm install --save
复合命令的逻辑。
尽管是 Bash 解决方案,但以下解决方案描述了如何为特定项目实现此自定义逻辑。但是,此解决方案取决于以下条件:
- 当 运行 使用
npm install --save
复合命令时,从事您项目的开发人员必须将 shell 设置为 Bash。 - 从事您的项目的开发人员将需要自定义他们的 Bash startup files,即
~/.bashrc
并且可能~/.bash_profile
。 - 项目目录,即您希望自定义逻辑生效的项目目录,必须包含自定义
.bashrc
文件。
Bash 解法:
以下三个步骤是配置您的项目和操作系统所必需的,因此当开发人员 运行s 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= shift for el in "$@"; do [[ "$el" == "$word" ]] && return 0; done } log_warn_message() { local cmd_name= 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
文件:要使自定义逻辑,即上述
.bashrc
文件中的npm
函数生效,需要配置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
。
附加信息。
Setup/Configuration 帮手:
考虑您的开发人员使用以下两个命令来帮助配置他们的 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
我的shell配置成Bash了吗?
要检查 shell 是否配置为 Bash 您可以创建一个新会话,即创建一个新终端 window 和 运行:
echo [=15=]
如果它打印 -bash
那么它正在使用 Bash.
如何将 shell 配置为 Bash?
如果 echo [=54=]
不打印 -bash
,那么您需要更改 shell。将其更改为 Bash 运行:
chsh -s /bin/bash
注意:您需要创建一个新会话才能使此更改生效。
说明
项目具体
.bashrc
文件:此
.bashrc
文件包含一个名为npm
的 shell function。此函数的主体包含覆盖默认npm install|i --save
命令所需的逻辑。if
语句中指定的条件,即读到的部分;if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then ... fi
本质上是读取
$*
special parameter 以检查传递给npm
函数的参数是否以其中之一开头;install
,或者是 shorthand 等价的i
,以及--save
option/argument 是否也通过了。为了检查
安装一个包--save
参数是否存在,我们将$@
特殊参数传递给array_includes
函数。我们以不同方式处理此参数,因为--save
选项在复合命令中的位置可能不同。例如,用户可以通过 运行ning this;# 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
命令全局存在,那么我们 运行 伪“安装后”命令,即command npx snowpack
当
if
语句中指定的条件不满足时,即它们是false
,用户本质上是 运行ning 任何其他 npm 命令那不是npm install --save <pkg_name>
。因此,在else
分支中,我们 运行 按原样执行命令:command npm "$@"
~/.bashrc 文件:
Bash参考手册5.2 Bash Variables部分
PROMPT_COMMAND
变量描述如下:PROMPT_COMMAND
If set, the value is interpreted as a command to execute before the printing of each primary prompt (
$PS1
).因此,这行代码(再次出现):
PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'
加载“项目特定”
.bashrc
(如果存在的话),它又用npm
函数覆盖npm
命令。这本质上是为特定项目提供覆盖npm install --save
复合命令的机制。请参阅
@Cyrus
的 this answer 以获得进一步的解释。
使用较新版本的 Snowpack (>=2),您可以 运行 snowpack dev
并且它会监视您的 npm_modules
文件夹以寻找要构建的新模块。