一句話
如果你需要安裝的帶有CLI的npm包被某個(gè)項(xiàng)目依賴,請(qǐng)盡量使用--save-dev
而不要使用--global
安裝。
引子
在我們啟動(dòng)一個(gè)前端項(xiàng)目時(shí)懈糯,總會(huì)用到一些 npm 上的帶有 CLI 的包(package)赊颠,我們?cè)诿钚邢掳堰@些包當(dāng)作全局的系統(tǒng)命令來(lái)使用。比如 babel-cli
鸭轮,express-generator
,browserify
等等橄霉。我們往往在需要使用它們時(shí)這樣做:
npm install -g babel-cli
之后窃爷,我們就理所當(dāng)然的使用它們了:
babel script.js -o script-compiled.js
可是,這樣真的好嗎姓蜂?
你在這樣做時(shí)按厘,也隱隱約約感覺到,這或許有些“臟”(dirty)钱慢,有點(diǎn)像是泛濫的全局對(duì)象逮京。
剝開看看
這種感覺沒有錯(cuò),拿 OSX 舉例來(lái)說束莫,如果我們使用 npm bin -g
來(lái)查看npm的全局包都裝到哪了懒棉,會(huì)得到這樣的結(jié)果:
/usr/local/bin
這個(gè)目錄是系統(tǒng)中用來(lái)存放需要本地全局使用的二進(jìn)制可執(zhí)行文件的地方,屬于系統(tǒng)環(huán)境的一部分览绿,往往不僅僅被某個(gè)或某些應(yīng)用依賴策严。
問題在哪
我們將帶有CLI的npm包分為兩類(非等價(jià)類):
- 工程級(jí)
- 系統(tǒng)級(jí)
如果我們僅僅是在現(xiàn)在的(或?qū)?lái))某個(gè)項(xiàng)目中打算使用它,那么這類包更偏向于 工程級(jí)饿敲。比如之前文中提到的 browserify
或 babel-cli
妻导。
如果我們更需要將它作為系統(tǒng)中的應(yīng)用,而不限于在某個(gè) Node.js 項(xiàng)目中依賴它怀各,那么這類包更偏向于 系統(tǒng)級(jí)倔韭。比如 作為Node.js版本管理器的n
。
更直接一點(diǎn)說瓢对,如果某個(gè)npm包不被任何項(xiàng)目或應(yīng)用依賴狐肢,那么它即屬于 系統(tǒng)級(jí)
對(duì)于工程級(jí)的npm包,如果我們進(jìn)行全局安裝沥曹,那么會(huì)帶來(lái)兩個(gè)問題:
- 全局安裝的包會(huì)作為系統(tǒng)環(huán)境的一部分份名,但同一系統(tǒng)下的不同項(xiàng)目可能對(duì)于其依賴版本不同。
- 項(xiàng)目在遷移或更換環(huán)境時(shí)妓美,沒有顯性的依賴表明新環(huán)境需要該npm包
如何解決
npm 提供了一種針對(duì)于開發(fā)過程中依賴的安裝方法:
npm install --save-dev <package>
使用這種方法安裝的包僵腺,會(huì)在 package.json
中被顯性指出在 devDependencies
中:
{
"name": "my_package",
"version": "1.0.0",
"dependencies": {
"my_dep": "^1.0.0"
},
"devDependencies" : {
"my_test_framework": "^3.1.0"
}
}
但這還有一個(gè)問題,如果使用 npm install --save-dev
安裝的包壶栋,如何在項(xiàng)目中使用CLI呢辰如?
首先,通過 --save-dev
安裝的包的可執(zhí)行文件都被放到了項(xiàng)目中的 ./node_modules/.bin/
中贵试。所以琉兜,我們可以通過該目錄執(zhí)行需要本地運(yùn)行的CLI命令凯正,比如:
./node_modules/.bin/babel script.js -o script-compiled.js
更進(jìn)一步,我們也可以把命令放入package.json
的scripts
中豌蟋,比如:
{
...
"scripts": {
"babel": "babel"
}
}
因?yàn)閚pm會(huì)在執(zhí)行時(shí)首先檢查當(dāng)前項(xiàng)目中的 ./node_moduels/.bin/
目錄廊散,這樣在執(zhí)行時(shí)只需要輸入:
npm run babel -- script.js -o script-compiled.js
注意,傳遞參數(shù)前需要加 --
梧疲。
另外允睹,還可以把 ./node_modules/.bin/
加入到系統(tǒng)環(huán)境變量 PATH
中,但這樣只能在包含 node_modules
的項(xiàng)目目錄下使用CLI命令幌氮。這種做法其實(shí)更加增多了項(xiàng)目對(duì)系統(tǒng)環(huán)境的隱性依賴缭受,不推薦。
結(jié)論
古人有云:“兩害相較该互,則取其輕”米者。相比之前全局安裝,使用 --save-dev
安裝的npm包宇智,在執(zhí)行CLI命令時(shí)的確會(huì)比較麻煩蔓搞,但這樣做的好處也是顯而易見且更為重要的,而對(duì)于增加的使用成本普筹,另有許多成熟方法可以解決败明。在我們使用npm時(shí)隘马,對(duì)于 工程級(jí) 和 系統(tǒng)級(jí) 的包的區(qū)分有時(shí)并不是那么明顯太防,希望通過這篇文章能讓大家意識(shí)到使用全局安裝的意義,并在管理項(xiàng)目依賴時(shí)多一些思考酸员。
參考