文章目錄
- 前言
- 原理解析
- 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
。 - 這樣可以保證你用的是本地依賴的版本,而不是全局安裝的版本。