npx

从本地或远程 npm 包运行命令

选择命令行版本:

概要

🌐 Synopsis

npx -- <pkg>[@<version>] [args...]
npx --package=<pkg>[@<version>] -- <cmd> [args...]
npx -c '<cmd> [args...]'
npx --package=foo -c '<cmd> [args...]'

描述

🌐 Description

此命令允许你从 npm 包运行任意命令(无论是本地安装的还是远程获取的),其运行环境与通过 npm run 运行时类似。

🌐 This command allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via npm run.

通过 --package 选项指定的任何软件包都将与任何本地安装的软件包可执行文件一起,在执行的命令的 PATH 中提供。可以多次指定 --package 选项,以在提供的命令所需的环境中使用所有指定的软件包。

🌐 Whatever packages are specified by the --package option will be provided in the PATH of the executed command, along with any locally installed package executables. The --package option may be specified multiple times, to execute the supplied command in an environment where all specified packages are available.

如果任何请求的包在本地项目依赖中不存在,它们将被安装到 npm 缓存中的一个文件夹,并在执行的进程中添加到 PATH 环境变量中。会显示一个提示(可以通过提供 --yes--no 来抑制)。

🌐 If any requested packages are not present in the local project dependencies, then they are installed to a folder in the npm cache, which is added to the PATH environment variable in the executed process. A prompt is printed (which can be suppressed by providing either --yes or --no).

未提供规范的包名将与本地项目中存在的任何版本匹配。带有规范的包名只有在与本地依赖的名称和版本完全相同时,才会被视为匹配。

🌐 Package names provided without a specifier will be matched with whatever version exists in the local project. Package names with a specifier will only be considered a match if they have the exact same name and version as the local dependency.

如果未提供 -c--call 选项,则使用位置参数来生成命令字符串。如果未提供 --package 选项,则 npm 将根据以下启发式规则尝试从作为第一个位置参数提供的软件包说明符中确定可执行文件的名称:

🌐 If no -c or --call option is provided, then the positional arguments are used to generate the command string. If no --package options are provided, then npm will attempt to determine the executable name from the package specifier provided as the first positional argument according to the following heuristic:

  • 如果包在 package.jsonbin 字段中只有一个条目,或者所有条目都是同一命令的别名,那么将使用该命令。
  • 如果封装有多个 bin 条目,并且其中一个与 name 字段的无作用域部分匹配,那么将使用该命令。
  • 如果这没有导致正好一个选项(要么是因为没有 bin 条目,要么是因为它们都不匹配包的 name),那么 npm exec 将以错误退出。

要运行除指定二进制文件之外的二进制文件,请指定一个或多个 --package 选项,这将阻止 npm 从第一个命令参数推断包。

🌐 To run a binary other than the named binary, specify one or more --package options, which will prevent npm from inferring the package from the first command argument.

npx 对比 npm exec

🌐 npx vs npm exec

通过 npx 可执行文件运行时,所有标志和选项必须在任何位置参数之前设置。通过 npm exec 运行时,可以使用双连字符 -- 标志来阻止 npm 解析应发送到执行命令的开关和选项。

🌐 When run via the npx binary, all flags and options must be set prior to any positional arguments. When run via npm exec, a double-hyphen -- flag can be used to suppress npm's parsing of switches and options that should be sent to the executed command.

例如:

🌐 For example:

$ npx foo@latest bar --package=@npmcli/foo

在这种情况下,npm 将解析 foo 包名称,并运行以下命令:

🌐 In this case, npm will resolve the foo package name, and run the following command:

$ foo bar --package=@npmcli/foo

由于 --package 选项位于位置参数之后,它被视为传递给已执行命令的参数。

🌐 Since the --package option comes after the positional arguments, it is treated as an argument to the executed command.

相比之下,由于 npm 的参数解析逻辑,运行这个命令是不同的:

🌐 In contrast, due to npm's argument parsing logic, running this command is different:

$ npm exec foo@latest bar --package=@npmcli/foo

在这种情况下,npm 会先解析 --package 选项,解析 @npmcli/foo 包。然后,它将在该上下文中执行以下命令:

🌐 In this case, npm will parse the --package option first, resolving the @npmcli/foo package. Then, it will execute the following command in that context:

$ foo@latest bar

建议使用双连字符来明确告诉 npm 停止解析命令行选项和开关。因此,以下命令将等同于上面的 npx 命令:

🌐 The double-hyphen character is recommended to explicitly tell npm to stop parsing command line options and switches. The following command would thus be equivalent to the npx command above:

$ npm exec -- foo@latest bar --package=@npmcli/foo

示例

🌐 Examples

使用本地依赖中的 tap 版本,并提供以下参数运行:

🌐 Run the version of tap in the local dependencies, with the provided arguments:

$ npm exec -- tap --bail test/foo.js
$ npx tap --bail test/foo.js

通过指定 --package 选项来运行与包名匹配的命令以外的其他命令:

🌐 Run a command other than the command whose name matches the package name by specifying a --package option:

$ npm exec --package=foo -- bar --bar-argument
# ~ or ~
$ npx --package=foo bar --bar-argument

在当前项目的上下文中运行任意 shell 脚本:

🌐 Run an arbitrary shell script, in the context of the current project:

$ npm x -c 'eslint && say "hooray, lint passed"'
$ npx -c 'eslint && say "hooray, lint passed"'

与旧 npx 版本的兼容性

🌐 Compatibility with Older npx Versions

npx 二进制文件在 npm v7.0.0 中被重写,同时独立的 npx 包在那时被弃用。npx 使用 npm exec 命令,而不是单独的参数解析器和安装流程,并提供了一些机制以保持与之前版本接受的参数的向后兼容性。

🌐 The npx binary was rewritten in npm v7.0.0, and the standalone npx package deprecated at that time. npx uses the npm exec command instead of a separate argument parser and install process, with some affordances to maintain backwards compatibility with the arguments it accepted in previous versions.

这导致其功能发生了一些变化:

🌐 This resulted in some shifts in its functionality:

  • 可以提供任何 npm 配置值。
  • 为了防止因输入错误的包名而引发的安全和用户体验问题,npx 会在安装任何东西之前提示确认。可以使用 -y--yes 选项来取消此提示。
  • --no-install 选项已被弃用,将转换为 --no
  • Shell 后备功能已被删除,因为它是不可取的。
  • -p 参数在 npm 中是 --parseable 的简写,但在 npx 中是 --package 的简写。这是被保留的,但仅适用于 npx 可执行文件。
  • --ignore-existing 选项已被移除。本地安装的二进制文件始终存在于执行的进程 PATH 中。
  • --npm 选项已被移除。npx 将始终使用其自带的 npm
  • --node-arg-n 选项已被移除。
  • --always-spawn 选项是多余的,因此已被移除。
  • --shell 选项被 --script-shell 替代,但为了向后兼容,仍保留在 npx 可执行文件中。

也可以看看

🌐 See Also