将它包装在一个 shell 函数中应该可以解决问题:
"test": "f() { if [ $# -eq 0 ]; then mocha './test/**/*.test.js'; else mocha -- \"$@\"; fi; }; f"
请注意,我稍微更改了 if 条件和 else 分支,因此您可以在必要时指定多个文件参数。
更简洁的方法:
"test": "f() { mocha -- \"${@:-./test/**/*.test.js}\"; }; f"
以这种方式使用 shell 函数可能看起来很熟悉,因为 git aliases 经常使用相同的技术。
详细说明
让我们用这个脚本来演示:
"scripts": {
"myscript": "if [ \"$1\" = one ]; then printf %s\\\\n \"$@\"; else echo false; fi"
}
这里如果第一个参数是“一个”,我们打印所有的参数,否则我们打印“假”。我们当然假设 npm run-script 使用的是类似 sh 的 shell,而不是例如 Windows 的 cmd.exe。
我在npm documentation 中看不到任何具体详细说明如何 将参数传递给脚本的内容,所以让我们看一下源代码(撰写本文时的 npm v6.14.7 )。似乎该脚本与其参数here 结合在一起,然后执行here。本质上,npm run myscript -- one two three 变成了
sh -c 'if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi "one" "two" "three"'
我们的参数one two three 被简单地引用转义并连接到脚本命令。就 shell 语法而言,这意味着它们最终会成为 fi 的参数。 sh 当然会拒绝这一点,因为 fi 只是结束 if 的内置函数,并且不接受任何参数。
我们的目标更像是
sh -c 'if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi' sh "one" "two" "three"
这里 one、two 和 three 是 sh 本身的参数,因此成为给定脚本中的参数变量 $1、$2 和 $3。 npm 不允许我们直接这样做,但我们可以通过将脚本包装在 shell 函数中来完成同样的事情:
"scripts": {
"myscript": "f() { if [ \"$1\" = one ]; then printf %s\\\\n \"$@\"; else echo false; fi; }; f"
}
此处的脚本以函数调用结束,因此 npm 最终会将参数连接到此调用,最终将函数调用为 f "one" "two" "three":
sh -c 'f() { if [ "$1" = one ]; then printf %s\\n "$@"; else echo false; fi; }; f "one" "two" "three"'