更多npm常用模塊使用請訪問:npm常用模塊匯總
npm 從5.2版開始,增加了 npx 命令。它有很多用處,本文介紹該命令的主要使用場景。
Node 自帶 npm 模塊,所以可以直接使用 npx 命令。萬一不能用,就要手動安裝一下。
npm install -g npx
npx到底能干什么?
我們知道一般的node項目會用到各種工具和腳手架,我們通常使用兩種命令安裝,npm install -g xxx
(全局安裝)和npm install -d xxx
(本地安裝)。
全局安裝劣勢:
- 占用本機空間
npm會在機器上創建一個目錄(mac是/usr/local/lib/node_modules)存放所有global安裝的包, 其實node_module占用的空間比較大的 - 版本問題:
假如一個項目中的某一個依賴是全局安裝的,也就意味着不同的開發人員使用的這個依賴版本完全基於本地的版本,也就會導致不同的開發人員使用不同的版本(例如:是不是你和同事本地的node、eslint、webpack等工具版本會不一樣?你是不是很苦惱?)
npx 的出現就是幫你解決全局安裝依賴和版本問題的。
當在執行npx <command>
的時候,npx會做什么事情?
- 幫你在本地(可以是當前項目中的也可以是本機全局)尋找這個
command
- 找到了: 就用本地的版本
- 沒找到: 直接下載最新版本,完成命令要求
- 使用完之后不會在你的本機或者項目留下任何東西
npx 優勢也就很明顯了:
- 不會污染本機
- 永遠使用最新版本的依賴
npx使用介紹
調用項目安裝的模塊
npx 調用項目內部安裝的模塊。比如,之前使用npm在項目內部安裝了測試工具 Mocha。
npm install -d mocha
調用 Mocha ,只能在項目腳本和 package.json
的scripts
字段里面, 如果想在命令行下調用,必須像下面這樣。
# 項目的根目錄下執行
node-modules/.bin/mocha --version
npx 就是想解決這個問題,讓項目內部安裝的模塊用起來更方便,只要像下面這樣調用就行了。
npx mocha --version
npx 的原理很簡單,就是運行的時候,會到node_modules/.bin
路徑和環境變量$PATH
里面,檢查命令是否存在。如果依然找不到,就會幫你安裝。(只會在你執行命令所在目錄的依賴文件里和本機全局去找,不會去執行當前命令目錄的‘隔壁鄰居’項目去找!!!)
由於 npx 會檢查環境變量$PATH
,所以系統命令也可以調用。
# 等同於 ls
npx ls
注意,Bash
內置的命令不在$PATH
里面,所以不能用。比如,cd
是 Bash
命令,因此就不能用npx cd
。
避免全局安裝模塊
除了調用項目內部模塊,npx
還能避免全局安裝的模塊。比如,create-react-app
這個模塊是全局安裝,npx
可以運行它,而且不進行全局安裝。
npx create-react-app my-react-app
上面代碼運行時,如果項目依賴和本機全局都沒有安裝腳手架的話,npx
將create-react-app
下載到一個臨時目錄(cache目錄),使用以后再刪除。所以,以后再次執行上面的命令,都會重新下載create-react-app
,執行完命令都會刪除create-react-app
。
下載全局模塊時,npx 允許指定版本。
npx uglify-js@3.1.0 main.js -o ./dist/main.js
上面代碼指定使用 3.1.0 版本的uglify-js
壓縮腳本。
注意,只要 npx
后面的模塊無法在本地發現,就會下載同名模塊。比如,本地沒有安裝http-server
模塊,下面的命令會自動下載該模塊,在當前目錄啟動一個 Web 服務。
npx http-server
--no-install 參數和--ignore-existing 參數
如果想讓 npx 強制使用本地模塊,不下載遠程模塊,可以使用--no-install
參數。如果本地不存在該模塊,就會報錯。
npx --no-install http-server
反過來,如果忽略本地的同名模塊,強制安裝使用遠程模塊,可以使用--ignore-existing
參數。比如,本地已經全局安裝了create-react-app,但還是想使用遠程模塊,就用這個參數。
npx --ignore-existing create-react-app my-react-app
使用不同版本的 node
利用 npx 可以下載模塊這個特點,可以指定某個版本的 Node 運行腳本。它的竅門就是使用 npm 的 node 模塊。
npx node@0.12.8 -v
v0.12.8
上面命令會使用 0.12.8 版本的 Node 執行腳本。原理是從 npm 下載這個版本的 node,使用后再刪掉。
某些場景下,這個方法用來切換 Node 版本,要比 nvm 那樣的版本管理器方便一些。
-p 參數
npx的-p選項允許您指定要安裝的包,並將其添加到正在運行的$PATH中。
-p
參數用於指定 npx 所要安裝的模塊,所以上一節的命令可以寫成下面這樣。
npx -p node@0.12.8 node -v
v0.12.8
上面命令先指定安裝node@0.12.8
,然后再執行node -v
命令。
-p
參數對於需要安裝多個模塊的場景很有用。
npx -p lolcatjs -p cowsay [command]
使用npx -p node@6 npm run test
:
- npx會幫助你下載
node@6
- 將此時的環境變成
node@6
版本 - 使用
node@6
幫你執行npm run test
- 命令執行完畢之后不會修改你原來的node版本
指令可以理解為使用node@6
版本運行npm run test
-c 參數
如果 npx 安裝多個模塊,默認情況下,所執行的命令之中,只有第一個可執行項會使用 npx 安裝的模塊,后面的可執行項還是會交給 Shell 解釋。
npx -p lolcatjs -p cowsay 'cowsay hello | lolcatjs'
# 報錯
上面代碼中,cowsay hello | lolcatjs
執行時會報錯,原因是第一項cowsay
由 npx 解釋,而第二項命令localcatjs
由 Shell
解釋,但是lolcatjs
並沒有全局安裝,所以報錯。
-c
參數可以將所有命令都用 npx 解釋。有了它,下面代碼就可以正常執行了。
npx -p lolcatjs -p cowsay -c 'cowsay hello | lolcatjs'
-c
參數的另一個作用,是將環境變量帶入所要執行的命令。舉例來說,npm 提供當前項目的一些環境變量,可以用下面的命令查看。
npm run env | grep npm_
-c
參數可以把這些 npm 的環境變量帶入 npx 命令。
npx -c 'echo "$npm_package_name"'
上面代碼會輸出當前項目的項目名。
例子:
像之前我們使用yo創建webapp項目的時候,分三步安裝的:
先安裝yo
npm install yo -g
再安裝 generator
npm install -g generator-webapp
最后再創建webapp項目
yo webapp
那么我們現在用npx就可以一條命令安裝了,這樣本機全局既不會有yo和generator的包,還省去了兩次命令操作,是不是非常簡單了呀,命令如下:
npx -p yo -p generator-webapp -c yo webapp
-p
后面跟着需要安裝的模塊,可以連續安裝多個-c
后面跟着需要執行的命令
執行 GitHub 源碼
npx 還可以執行 GitHub 上面的模塊源碼。
# 執行 Gist 代碼
npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32
# 執行倉庫代碼
npx github:piuccio/cowsay hello
注意,遠程代碼必須是一個模塊,即必須包含package.json
和入口腳本。
參考:
npx 使用教程