我开始玩Snowpack。与Webpack相比,它采取了与Webpack不同的方法,即在安装各个软件包后立即捆绑它们。
“问题”是,当我安装软件包时,我必须首先运行npm install --save my-package
,然后必须手动将其与npx snowpack
一起打包。 Snowpack docs提到,我可以包含一个prepare
脚本,该脚本将在运行snowpack
后npm install
进行所有操作,但不适用于单个软件包,仅适用于通用{{1 }} npm install
中的所有依赖项。据我所知,npm docs中提到的所有npm挂钩都是这种情况。
安装单个软件包时,有什么方法可以自动运行脚本吗?我能想到的唯一方法是覆盖安装脚本并向其中添加一些内容。在GitHub或其他地方有任何示例吗?
更新:为澄清起见,我每次安装带有package.json
的新软件包时都希望运行npx snowpack
,但最好不要安装--save
--save-dev
。这对于任何软件包都不会有什么不同。这将特定于某个回购/项目,而不是系统上的全局项目。
仅运行--save
之后运行snowpack
是不够的,就像您迷上了npm install
或postinstall
一样。另外,我想确保从事我的项目的开发人员可以像往常一样使用release
,然后运行npm install --save newdep
。我不想要求开发人员使用自定义的命名脚本。
答案 0 :(得分:5)
简短答案::不幸的是,npm不提供任何内置功能来满足您的要求。
诸如postinstall
之类的生命周期挂钩/脚本仅在运行通用npm install
命令时被调用,而在项目开发阶段仅当某人运行npm install --save <pkg_name>
时才被调用。
解决方法:考虑通过在外壳层级别实质上覆盖npm
命令来定制npm install --save
复合命令的逻辑。
以下解决方案(尽管是Bash解决方案)描述了如何针对特定项目实现这种自定义逻辑。但是,此解决方案取决于以下条件:
npm install --save
复合命令时,从事项目工作的开发人员必须将shell设置为Bash。~/.bashrc
,甚至可能是~/.bash_profile
。.bashrc
文件。以下三个步骤是配置项目和操作系统所必需的,因此,当开发人员运行npm install --save <pkg_name>
(或其变体)时,npx snowpack
命令随后被调用。 / p>
注意:第二点和第三点(下面)是开发人员执行(一次)自定义其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配置为读取上述“特定于项目” { {1}}文件。要进行配置,请将以下代码行添加到.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启动文件。
对于第二步,运行以下命令:
~/.bash_profile
这会将echo $'\n'"PROMPT_COMMAND='if [[ \"\$bashrc\" != \"\$PWD\" && \"\$PWD\" != \"\$HOME\" && -e .bashrc ]]; then bashrc=\"\$PWD\"; . .bashrc; fi'" >> ~/.bashrc
行代码添加到现有的PROMPT_COMMAND=...
文件中,或者如果尚不存在,则创建一个新文件:
对于第三步,运行以下命令以在~/.bashrc
中添加用于加载~/.bash_profile
文件的代码行:
~/.bashrc
我的shell是否配置为Bash?
要检查外壳是否配置为Bash,可以创建一个新会话,即创建一个新的Terminal窗口并运行:
echo $'\n'"if [ -f ~/.bashrc ]; then . ~/.bashrc; fi" >> ~/.bash_profile
如果打印出echo $0
,则表明它正在使用Bash。
如何将我的shell配置为Bash?
如果-bash
不打印echo $0
,则需要更改外壳。要将其更改为Bash,请运行:
-bash
注意:您需要创建一个新会话以使此更改生效。
项目特定的chsh -s /bin/bash
文件:
此.bashrc
文件包含名为.bashrc
的{{3}}。该函数的主体包含重写默认npm
命令所必需的逻辑。
npm install|i --save
语句中指定的条件,即读取的部分;
if
基本上读取if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then
...
fi
shell function来检查传递给$*
函数的参数是否以其中一个开头; 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}}。
注意::我在此检查中的逻辑假设您将在全局安装1
。但是,如果要在项目中本地安装npx
,则需要更改此逻辑。也许通过检查npm
是否存在。或者,您可能会确信./node_modules/.bin/npx
命令将始终存在,因此得出结论认为此检查是不必要的。
如果npx
命令是全局存在的,那么我们运行伪的“ postinstall”命令,即
npx
如果不满足command npx snowpack
语句中指定的条件,即它们为if
,则用户实际上正在运行不是false
的任何其他npm命令。因此,在npm install --save <pkg_name>
分支中,我们按原样运行命令:
else
〜/ .bashrc文件:
“ Bash参考手册”的special parameter部分中,command npm "$@"
变量的描述如下:
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
的{{3}}。
答案 1 :(得分:0)
我认为最好的选择是创建一个执行所需动作的新脚本。 package.json中的以下内容:
{
"scripts": {
"snowpack-install" : "npm install --save && npx snowpack"
}
}
您实际上可以在package.json中使用postinstall option。后安装将运行“安装软件包后”。看起来类似于以下内容:
{
"scripts": {
"postinstall" : "npx snowpack"
}
}
答案 2 :(得分:0)
使用更新版本的Snowpack(> = 2),您可以运行snowpack dev
,它将监视npm_modules
文件夹中要构建的新模块。