在已安装的“上下文”中运行 Node 命令 node_modules
,您可以在 scripts
中输入领域package.json
.例如:
...
"scripts": {
"test": "mocha --recursive test/**/*.js --compilers js:babel-register"
}
...
然后我可以输入
npm run test
在我的项目根目录中,将运行 mocha 测试(通过调用安装在 node_modules/mocha/bin
中的 mocha 二进制文件)。有没有办法在不创建脚本条目的情况下实现完全相同的行为?例如,一次性的“脚本”?
我正在想象类似以下的内容,相当于
npm run test
:npm cmd mocha --recursive test/**/*.js --compilers js:babel-register
有没有办法实现这一目标?
注意:我应该澄清我正在寻找真正的等效性。也就是说,我的命令应该能够访问其他脚本命令等。我知道您始终可以使用 node 和 node_modules 中的二进制文件的路径来调用二进制文件,但这不是一个适当的解决方案。
最佳答案
注意:此答案解决了 OP 的特定用例:在给定项目的上下文中调用依赖包的 CLI;这与使 CLI 全局可用无关 - 请参阅底部的讨论。
tl;博士:
在类 Unix 平台上 , 前置 npm run env --
到您的命令 ;例如。:
npm run env -- mocha --recursive test/**/*.js --compilers js:babel-register
此 不仅允许仅通过名称调用依赖 CLI,而且完全复制了
npm
的环境。套幕后使用 npm test
或 npm run-script <script-defined-in-package.json>
.遗憾的是,这种方法不适用于 Windows。
对于 Windows 解决方案、便利别名(包括每 session 一次的环境配置命令)和背景信息,请继续阅读。
有两个(不相互排斥)使 npm 项目的依赖项的 CLI 可从 shell 中仅通过名称调用的方法 :
Frxstrem's helpful answer在类 Unix 平台上为 (a) 提供了一个不完整的解决方案;但是,这可能就足够了,具体取决于您的特定需求。
它是不完整的,因为它只是将包含(符号链接(symbolic link))依赖 CLI 的目录添加到
$PATH
中。 ,而不执行调用 npm test
时发生的所有其他环境修改或 npm run-script <script-defined-in-package.json
.Unix 便利性和 Windows 解决方案
请注意 以下所有解决方案均基于
npm run env
,确保设置所有必要的环境变量,就像在项目的 package.json
中预定义的运行脚本时一样。文件与 npm test
或 npm run-script <script>
.这些环境修改包括:
$(npm prefix -g)/node_modules/npm/bin/node-gyp-bin
和项目目录的 ./node_modules/.bin
子目录,这是指向依赖项的 CLI 的符号链接(symbolic link)所在的位置,(临时)到 $PATH
环境变量。 npm_*
反射(reflect)项目设置的环境变量,例如 npm_package_version
以及 npm
/node
环境。 类 Unix 平台的便捷解决方案:
下面的两个解决方案都是 基于别名 ,在 (a) 的情况下是使用脚本的更轻量级的替代方案,在 (b) 的情况下是允许修改当前 shell 环境的先决条件(尽管也可以使用 shell 函数) .
为方便起见,将这些别名添加到您的 shell 配置文件/初始化中
文件 .
(a) 每次调用的助手:
定义
alias nx='npm run-script env --'
允许您通过添加
nx
来临时调用您的命令;例如。:nx mocha --recursive test/**/*.js --compilers js:babel-register
(b) 每 session 一次配置命令:
alias npmenv='npm run env -- $SHELL'
运行
npmenv
进入设置了 npm 环境的子 shell,允许直接(仅按名称)调用该子 shell 中的依赖 CLI。换句话说,按如下方式使用它:
cd ~/some-npm-project
npmenv # after this, you can run dependent CLIs by name alone; e.g., `mocha ...`
# ... run your project-specific commands
exit # exit the child shell before you switch to a different project
视窗解决方案:
(a) 和 (b) :请注意,Windows(与类 Unix 平台上的类 POSIX shell 不同)不(直接)支持传递范围仅限于单个命令的环境变量,因此下面的命令,即使传递了要执行的特定命令(案例(a )),也总是修改 session 的环境(情况(b))。
PowerShell (也适用于 Unix 版本):
将以下函数添加到您的
$PROFILE
(特定于用户的配置文件脚本):function npmenv($commandIfAny) {
npm run env -- |
? { $_ -and $_ -notmatch '^>' -and $_ -match '^[a-z_][a-z0-9_]+=' } |
% { $name, $val = $_ -split '='; set-item -path "env:$name" -value $val }
if ($?) {
if ($commandIfAny) {
& $commandIfAny $Args
}
}
}
cmd.exe
(常规命令提示符,常被误称为“DOS 提示符”):创建一个名为
npmenv.cmd
的批处理文件,将其放在您的 %PATH%
中的文件夹中,并定义如下:@echo off
:: Set all environment variables that `npm run env` reports.
for /f "delims==; tokens=1,*" %%i in ('npm run env ^| findstr /v "^>"') do set "%%i=%%j"
:: Invoke a specified command, if any.
%*
用法 (
cmd.exe
和 PowerShell):对于用例 (b),简单地调用为
npmenv
没有论据;之后,您可以仅通过名称 ( mocha ...
) 调用依赖 CLI。对于用例 (a),添加
npmenv
听你的命令;例如。: npmenv mocha --recursive test/**/*.js --compilers js:babel-register
警告:如前所述,第一次调用
npmenv
- 无论有无参数 - 总是修改 %PATH%
/$env:PATH
session 剩余时间的变量。如果您在同一 session 中切换到不同的项目,请确保运行
npmenv
(至少一次),但请注意,这将附加目录添加到 %PATH%
,因此如果它不是当前项目的已安装依赖项,您仍然可能会意外地运行先前项目的可执行文件。从 PowerShell 中,您实际上可以结合这两种解决方案来获得不同的 (a) 和 (b) 功能:定义
*.cmd
将上面的文件作为一个不同的命令(使用不同的名称,例如 nx.cmd
),您只与参数 (a) 一起使用,并重新定义 PowerShell 函数以用作无参数环境仅修改补充 (b)。这是有效的,因为 PowerShell 总是运行
*.cmd
不能影响当前 PowerShell session 环境的子进程中的文件。关于问题范围和此答案的说明:
OP 的问题是关于在给定项目的上下文中临时调用已安装的依赖包的 CLI,仅通过可执行名称 - 就像
npm
允许你在命令中添加 scripts
关键在 package.json
文件。问题不在于使 CLI 全局可用(通过使用
npm install -g
安装它们)。事实上,如果你想创作模块化的、自包含的包,不要依赖全局安装的包。相反,将所有依赖包作为项目的一部分:使用
npm install --save
(对于运行时依赖项)和 npm install --save-dev
(仅适用于开发时间的依赖项)- 参见 https://docs.npmjs.com/cli/install特别是,如果给定的 CLI 已经作为依赖项安装,那么全局安装它(可能是不同的版本)不仅是多余的,而且会混淆何时执行哪个版本。
关于javascript - 在没有 "npm run x"条目的情况下实现 "scripts"行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39990788/