Skip to content
大纲

npx

如果用过 Node.js, 那一定用过 npm, 但 npx 又是什么呢?


npm 是随 Node.js 一同安装的包管理工具, 通过它可本地或全局安装依赖库并管理其版本。

npm 本身不会运行任何库, 当 npm 执行安装库的指令时(npm install xxx), npm 会创建指向它们的链接:

  1. 全局安装会在全局安装的 npm 文件夹下创建链接, 可以用 npm root -g 命令来查看 npm 所在文件夹, npm 安装时会自动配置 $PATH 环境变量, 指向 npm 所在文件夹, 所以通过 npm 安装某些命令行工具时, 只有全局安装终端才能识别相应命令, 局部安装识别不了。
  2. 局部安装会在工程目录的 ./node_modules/.bin/ 文件夹中创建链接

当需要执行库时, 全局安装时终端能识别相应指令, 但局部安装的却有些繁琐:

  1. 可以直接使用相对路径来调用安装的包
shell
./node_modules/.bin/your-package
  1. 在 package.json 文件中添加脚本, 如
json
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "scripts": {
    "your-package": "your-package"
  }
}

然后运行指令

shell
npm run your-package

这两种方式实际上是一样的, 只是 npm run 会自动添加 ./node_module/.bin/

只凭借 npm, 如果想要运行某些库, 不安装是不行的 😑 😑 😑

npx

npm 从 5.2 版本开始, 增加了 npx 命令, 它是一个 npm 包的执行器 😍 😍 😍

只要 npm 的版本在 5.2 以上可直接使用 npx 命令, 万一不能用, 建议升级一下 Node 版本, 也可直接安装 npx

shell
npm install npx -g

DANGER

npx 的原理很简单, 在运行的时候, 首先会检查工程目录 ./node_modules/.bin 路径, 再检查环境变量 $PATH 查看命令是否存在, 如果存在则会使用相应的本地模块, 当这两个路径都不能找到相应命令时, 会下载远程模块至临时目录, 在使用完毕之后删除。

由于 npx 会检查环境变量 $PATH, 所以系统命令也可以调用

shell
# 等同于 ls
npx ls

需要注意的是, Bash 内置的命令不在 $PATH 里, 所以不能用。比如, cd 是 Bash 命令, 因此不能用 npx cd

利用 npx, 可以临时安装可执行依赖包, 不用全局安装, 避免全局污染, 例如在本地没有安装 http-server 模块的情况下, 可以随时启动一个 Web 服务 🐂 🐃 🐄

shell
npx http-server

WARNING

如果想让 npx 强制使用本地模块, 不下载远程模块, 可以使用 --no-install 参数。如果本地不存在该模块, 就会报错。

shell
npx --no-install http-server

反过来, 如果想忽略本地模块, 强制使用安装远程模块, 可以使用 --ignore-existing 参数。

shell
npx --ignore-existing create-react-app my-react-app

使用不同版本的 node

利用 npx 可以下载模块的特点, 还可以指定某个版本的 Node 运行脚本, 在某些场景下, 可利用它切换 Node 版本

shell
npx node@17.7.2 -v

安装多模块

npx 的 -p 参数用于指定 npx 所要安装的模块, 对于需要安装多个模块的场景很有用

shell
npx -p lolcatjs -p cowsay [command]
npx -p node@17.7.2 node -v

运行多指令

在安装多模块时, 默认情况下, 只有第一个可执行项会使用 npx 安装的模块, 后面的可执行项还是会交给 Shell 解释。

shell
npx -p lolcatjs -p cowsay 'cowsay hello | lolcatjs'       # 报错

上面代码中, cowsay hello | lolcatjs 执行时会报错, 原因是第一项 cowsay 由 npx 解释, 而第二项命令 lolcatjs 由 Shell 解释, 但是 lolcatjs 并没有全局安装, 所以报错。

-c 参数可以将所有的命令都用 npx 解释

shell
npx -p lolcatjs -p cowsay -c 'cowsay hello | lolcatjs'

执行 github 源码

npx 还可以执行 Github 上面的模块代码, 但需要注意的是, 远程代码必须是一个模块, 即必须包含 package.json 和 入口脚本

shell
npx github地址

总结

npx 是一个 npm 包的执行器, 在运行的时候, 首先会检查工程目录 ./node_modules/.bin 路径, 再检查环境变量 $PATH 查看命令是否存在, 如果存在则会使用相应的本地模块, 当这两个路径都不能找到相应命令时, 会下载远程模块至临时目录, 在使用完毕之后删除。

Mochi's personal blog.