npx 的作用以及延伸知识(.bin目录,npm run xx 执行)
文章目录
- 前言
- 原理解析
- 1. npx 的作用
- 2. 为什么会有 `node_modules/.bin/lerna`
- 3. npx 的查找顺序
- 4. 执行流程
- 总结1:
- 1. `.bin` 机制
- 什么是 `node_modules/.bin`?
- 例子
- 2. npx 的底层实现
- npx 是如何工作的?
- 为什么推荐用 npx?
- npx 的特殊能力
- 3. yarn 的机制
- 总结2:
- `.bin` 目录的实际内容
- 1. `.bin` 目录的作用
- 2. 实际内容举例
- 3. 如何查看 .bin 目录内容
- 4. 这些文件的作用
- 5. 关联知识
前言
在终端执行 lerna run build 时出现了 bash: lerna: command not found
的错误。这说明当前环境下找不到 lerna 命令
那么 npx lerna run build
为什么会自动使用本地 node_modules/.bin
下的 lerna,以及其原理。
原理解析
1. npx 的作用
npx
是 Node.js 附带的一个命令行工具(npm 5.2+),用于临时调用项目依赖中的可执行文件(bin)。- 当你在项目根目录下运行
npx lerna run build
时,npx
会优先在当前项目的node_modules/.bin
目录下查找lerna
可执行文件。
2. 为什么会有 node_modules/.bin/lerna
- 当你在项目的
package.json
里声明了lerna
作为devDependencies
,并执行过npm install
或yarn install
后,lerna
的可执行文件就会被自动放到node_modules/.bin/lerna
。 - 这个
.bin
目录是 npm/yarn 的标准机制,用于存放所有依赖包的命令行工具。
3. npx 的查找顺序
npx
会先查找本地node_modules/.bin
,如果找不到才会去全局环境查找。- 这样可以确保你用到的是当前项目依赖的 lerna 版本,而不是全局安装的版本,保证了版本一致性和可移植性。
4. 执行流程
- 你输入
npx lerna run build
npx
查找node_modules/.bin/lerna
- 找到后,直接调用这个本地的 lerna 执行
run build
命令 - lerna 会根据你的 monorepo 配置,依次在各个包下执行
build
脚本
总结1:
npx
让你无需全局安装 lerna,也不用关心 PATH 配置,直接用本地依赖的 lerna。- 这样做可以保证团队协作时每个人用的 lerna 版本一致,避免“在我电脑上没问题”的情况。
下面一步步详细讲解 npm/yarn 的 .bin
机制和 npx 的底层实现原理。
1. .bin
机制
什么是 node_modules/.bin
?
- 当你用 npm 或 yarn 安装依赖时(无论是全局还是本地),如果某个包的
package.json
里有"bin"
字段,npm/yarn 会自动把这些可执行文件的快捷方式(Windows 下是.cmd
文件,Unix 下是软链接)放到当前项目的node_modules/.bin
目录下。 - 这样你就可以在命令行里直接运行这些工具,而不用写完整路径。
例子
比如你安装了 lerna
作为 devDependencies:
npm install lerna --save-dev
此时会生成:
node_modules/.bin/lerna.cmd # Windows 下的可执行脚本
node_modules/.bin/lerna # Unix 下的软链接
这些文件实际上会调用 node_modules/lerna/cli.js
或类似的入口文件。
2. npx 的底层实现
npx 是如何工作的?
- 当你运行
npx lerna run build
时,npx 会在以下路径顺序查找lerna
:- 当前目录下的
node_modules/.bin
- 全局安装的包
- 当前目录下的
- 找到后,npx 会直接调用这个可执行文件(比如
node_modules/.bin/lerna.cmd
),并把后面的参数传递给它。
为什么推荐用 npx?
- 保证你用的是当前项目依赖的版本,而不是全局的,避免版本冲突。
- 不需要全局安装,团队协作更方便。
npx 的特殊能力
- 如果本地没有找到命令,npx 还可以临时下载并执行(但一般不推荐这样用,除非你明确需要)。
3. yarn 的机制
- yarn 也会自动在
node_modules/.bin
生成可执行文件。 - 当你用
yarn run xxx
时,yarn 会自动把node_modules/.bin
加入 PATH 环境变量,确保可以直接调用本地依赖的命令。
总结2:
node_modules/.bin
是 npm/yarn 自动生成的可执行文件目录,方便你直接运行依赖包的命令行工具。- npx 会优先使用本地
.bin
里的命令,保证项目一致性。 - 这套机制极大地方便了前端工程化和团队协作。
.bin
目录的实际内容
下面详细说明 .bin
目录的实际内容,并演示如何查看和理解它。
1. .bin
目录的作用
node_modules/.bin
目录用于存放所有依赖包(无论是本地依赖还是全局依赖)声明的可执行命令的快捷方式。这样你可以直接在命令行中运行这些工具,而不用写完整路径。
2. 实际内容举例
假设你的项目依赖了 lerna
、ts-jest
、jest
等包,执行完 npm install
或 yarn install
后,node_modules/.bin
目录下会出现如下内容(以 Windows 为例):
d:\001-study\js\getting-started-example\node_modules\.bin\
│
├── lerna.cmd
├── lerna
├── jest.cmd
├── jest
├── ts-jest.cmd
├── ts-jest
└── ...(其他依赖的可执行文件)
.cmd
文件是 Windows 下的批处理脚本,方便在命令行直接调用。
- 没有扩展名的文件是 Unix/Linux 下的可执行软链接或 shell 脚本。.ps1 是 PowerShell 脚本,给 PowerShell 用的。
3. 如何查看 .bin 目录内容
你可以在项目根目录下运行以下命令查看:
dir node_modules\.bin
或者更详细地查看所有文件:
dir node_modules\.bin /a
4. 这些文件的作用
- 这些文件实际上是指向各自依赖包的入口文件(如
node_modules/lerna/cli.js
)。 - 当你在命令行输入
lerna
或jest
时,系统会自动在node_modules/.bin
里查找并执行对应的脚本。
5. 关联知识
- 当你用
npx lerna
或yarn run lerna
时,实际上就是调用了node_modules/.bin/lerna
。 - 这样可以保证你用的是本地依赖的版本,而不是全局安装的版本。