实现" npm run x"没有"脚本的行为"进入?

时间:2016-10-12 04:56:50

标签: javascript node.js npm command-line-interface

在" context"中运行节点命令在已安装的node_modules中,您可以在scripts的{​​{1}}字段中输入内容。例如:

package.json

然后我可以在项目根目录中键入... "scripts": { "test": "mocha --recursive test/**/*.js --compilers js:babel-register" } ... ,然后运行mocha测试(通过调用npm run test中安装的mocha二进制文件)。

有没有办法实现完全相同的行为,但没有创建脚本条目?例如,对于一次性"脚本"?

我想象以下内容,相当于node_modules/mocha/bin

npm run test

有没有办法实现这个目标?

注意:我应该澄清一点,我正在寻找真正的等价。也就是说,我的命令应该能够访问其他脚本命令等。我知道你总是可以使用node和node_modules中二进制文件的路径来调用二进制文件,但这不是一个合适的解决方案。

3 个答案:

答案 0 :(得分:8)

注意:这个答案解决了OP的特定用例:在给定项目的上下文中调用依赖包的CLI ;关于使CLI 全球可用 < - > - 参见讨论的底部。

<强> TL; DR:

Unix 类平台上npm run env --添加到您的命令; e.g:

npm run env -- mocha --recursive test/**/*.js --compilers js:babel-register

不仅可以仅通过名称调用依赖CLI,还可以在使用npm或{{1}时完全复制幕后npm test设置的环境}。

可悲的是,这种方法在Windows上无法运行。

对于Windows解决方案,请继续阅读便利别名(包括每会话一次的环境配置命令)和背景信息。

有两种(不是相互排斥的)方法来制作npm项目的依赖关系&#39; CLI可以通过shell中的名称来调用

  • (a)使用 每次调用帮助程序命令将命令传递给
  • (b)运行 每会话一次命令(暂时)修改您的环境

Frxstrem's helpful answer为类似Unix的平台上的(a)提供不完整的解决方案;但是,可能,这取决于您的具体需求 它不完整,因为它只是将包含(符号链接)依赖CLI的目录添加到npm run-script <script-defined-in-package.json>,而不执行调用$PATHnpm test时发生的所有其他环境修改。 / p>

Unix便利性和Windows解决方案

请注意,以下所有解决方案均基于npm run-script <script-defined-in-package.json ,这可确保设置所有必需的环境变量,就像在项目预定义的运行脚本时一样npm run env文件package.jsonnpm test 这些环境修改包括:

  • 预先npm run-script <script>和项目目录的$(npm prefix -g)/node_modules/npm/bin/node-gyp-bin子目录,这是符号链接的依赖关系&#39; CLI(临时)位于./node_modules/.bin环境变量。
  • 定义反映项目设置的众多$PATH环境变量,例如npm_*以及npm_package_version / npm环境。

类Unix平台的便捷解决方案:

下面的两个解决方案都是 alias -based ,在(a)的情况下,它是使用脚本的更轻量级替代方案>,并且在(b)的情况下是允许修改当前shell环境的先决条件(尽管也可以使用shell函数)。

为方便起见,将这些别名添加到您的shell配置文件/初始化中 文件

(a)每次调用助手:

定义

node

允许您通过预先alias nx='npm run-script env --' 前缀来临时调用命令; e.g:

nx

(b)每会话一次配置命令:

nx mocha --recursive test/**/*.js --compilers js:babel-register

运行alias npmenv='npm run env -- $SHELL' 以使用npm环境集输入子shell ,允许直接(仅限名称)调用该子shell中的从属CLI。
换句话说,使用如下:

npmenv

Windows解决方案:

(a)(b):请注意,Windows(与类似Unix的平台上的类似POSIX的shell)不支持(直接)支持传递环境变量仅限于单个命令,因此下面的命令,即使在传递执行的特定命令(case(a))时,也总是修改会话的环境(例如(b))。

PowerShell (也适用于Unix版本):

将以下函数添加到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 (用户特定的配置文件脚本):

$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 } } } (常规命令提示符,经常错误地称为&#34; DOS提示符&#34;):

创建名为cmd.exe的批处理文件,将其放在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. %* 和PowerShell):

对于用例(b),简单地调用cmd.exe 而不带参数;之后,您可以仅通过名称(npmenv)调用依赖CLI。

对于用例(a),在命令前加上mocha ...; e.g:

npmenv

警告:如上所述, npmenv mocha --recursive test/**/*.js --compilers js:babel-register 第一次调用 - 无论是否有参数 - 总是会修改npmenv / %PATH%变量以用于其余部分会议。

如果您在同一会话中切换到其他项目,请务必再次运行$env:PATH(至少一次),但请注意,这会将其他目录添加到{{1}因此,如果不是现有项目的已安装依赖项,您仍然可能最终意外地运行以前项目的可执行文件。

从PowerShell中,您实际上可以组合这两个解决方案,以获得不同的(a)和(b)功能:将上面的npmenv文件定义为一个独特的命令(使用您只使用带有参数(a)的的不同名称,例如%PATH%),并重新定义PowerShell函数,以作为无参数环境修改的唯一补码(b)。 /> 这是有效的,因为PowerShell总是在进程中运行*.cmd个文件,这些文件不会影响当前的PowerShell会话环境。

关于问题范围和答案的说明:

OP的问题是关于在给定项目 ad-hoc的上下文中调用已安装的依赖包的CLI,仅仅是可执行名称 - 就像{{1}一样允许您执行添加到nx.cmd文件中*.cmd键的命令。

问题是关于使CLI 全球可用(通过使用npm安装它们)。

事实上,如果您想创建模块化,自包含的软件包,请依赖于全局安装的软件包。相反,使所有依赖包成为项目的一部分:使用scripts(对于运行时依赖性)和package.json(仅用于开发时依赖性) - 请参阅https://docs.npmjs.com/cli/install

特别是,如果给定的CLI已经作为依赖安装,那么全局以及(可能是不同的版本)安装它不仅是多余的,而是要求关于在何时执行哪个版本的混淆。

答案 1 :(得分:3)

我已将这个小脚本~/bin/npm-cmd保存在我的计算机上:

#!/bin/bash
PATH="$(npm bin):$PATH" "$@"

然后运行npm-cmd PROGRAMARGS应首先在PROGRAM中查找./node_modules/.bin,然后再回到正常查找。

答案 2 :(得分:0)

注意:此答案适用于所有平台。

npm i -g mocha

mocha --recursive test/**/*.js --compilers js:babel-register

Mocha CLI documentation(滚动到使用部分)。

如果您想从CLI运行 npm 包作为可执行文件,正确的方法是通过package.json bin 条目。它允许您将项目中的文件映射为可执行文件。如果它是节点脚本,那么文件的第一行(如普通脚本应以shebang#!/usr/bin/env node开头。

通过在package.json bin中映射这些文件,您可以从其他软件包脚本部分调用它们,或者在使用npm install -g <package>全局安装软件包时从cli调用它们。 bin 节点可以是将脚本名称映射到项目中的脚本文件的对象,如果要将多个脚本作为可执行文件添加到路径中,或者是您想要的单个文件的字符串路径充当您的包的可执行文件。

这实际上是你的例子中mocha使用的exact same mechanism

mocha bin

如果没有这个,在全局安装时,mocha将永远不会出现在您的路径中,并且无法通过脚本部分访问。