一文徹底看懂 package.json 中的各種 dependencies
共 3469字,需瀏覽 7分鐘
·
2024-05-15 07:08
package.json 中存在各種各樣的依賴定義:dependencies、devDependencies、peerDependencies、optionalDependencies、bundleDependencies,很容易讓初學(xué)的開發(fā)者暈頭,到底有什么區(qū)別。
依賴主要涉及到兩個(gè)場(chǎng)景:
在當(dāng)前項(xiàng)目的
package.json中的依賴定義當(dāng)前項(xiàng)目中安裝的包中的
package.json中的依賴定義
所以下面每個(gè)依賴項(xiàng)定義都會(huì)通過兩個(gè)維度來討論:定義在項(xiàng)目中和定義在依賴中。
dependencies
dependencies 表示該項(xiàng)目在運(yùn)行時(shí)所需要用到的依賴項(xiàng)。
然而作為最常見的依賴項(xiàng)定義,經(jīng)常會(huì)被不明所以的開發(fā)者誤用(dependencies 一把梭 ???♂?)。
定義在項(xiàng)目中
如果你開發(fā)的項(xiàng)目依賴于某個(gè)包來運(yùn)行,那么你就可以選擇將你所依賴的包添加到 dependencies 中。
install 時(shí)該依賴將會(huì)被下載,并可在項(xiàng)目的代碼中使用。
定義在依賴中
當(dāng)你開發(fā)一個(gè)項(xiàng)目需要用到一個(gè) A 包時(shí),假設(shè) A 包的 dependencies 中存在如下定義:
{
"dependencies": {
"B": "*"
}
}
復(fù)制代碼
那你在項(xiàng)目中安裝 A 包時(shí),無論你的項(xiàng)目是否依賴 B 包,B 包都會(huì)作為 A 包的依賴同時(shí)被安裝。
有些包的開發(fā)者可能會(huì)一股腦將各種依賴全部丟在包的 dependencies 中,這會(huì)導(dǎo)致開發(fā)者在使用該包時(shí),會(huì)安裝各種無用的包。
install 時(shí)該依賴會(huì)被下載,但是不應(yīng)該在你的項(xiàng)目中直接引用該包,因?yàn)樵摪陌惭b路徑會(huì)和包管理器行為相關(guān),會(huì)導(dǎo)致幽靈依賴現(xiàn)象。
devDependencies
devDependencies 表示在開發(fā)時(shí)所需要用到的或依賴的包。
定義在項(xiàng)目中
如果你的項(xiàng)目在開發(fā)中依賴某個(gè)包,但是在運(yùn)行時(shí)不依賴,則可以將該包添加到 devDependencies。
install 時(shí)該依賴將會(huì)被下載,可以在代碼中使用,但是請(qǐng)不要在項(xiàng)目要上線的代碼中使用。
注意當(dāng) NODE_ENV 為 production 時(shí),install 等效于 install --production,devDependencies 將不會(huì)被下載,這種場(chǎng)景一般常見于 node 項(xiàng)目中,比如開發(fā)時(shí)依賴測(cè)試庫(kù),但項(xiàng)目線上運(yùn)行不需要安裝測(cè)試庫(kù),但是一些前端項(xiàng)目在 CI/CD 中構(gòu)建時(shí)可能會(huì)遇到問題,有些 CI/CD 中的 NODE_ENV 環(huán)境變量默認(rèn)為 production,會(huì)導(dǎo)致在打包所需的依賴包不會(huì)被安裝。
定義在依賴中
install 時(shí)依賴包中的 devDependencies 將會(huì)被忽略,不會(huì)被安裝。
peerDependencies
peerDependencies 主要用于依賴包中,表示安裝該包時(shí)還需要安裝哪些包,乍一看非常類似 dependencies,不過場(chǎng)景和行為都存在一定差異。
定義在項(xiàng)目中
peerDependencies 主要用于依賴包中,在項(xiàng)目中不起作用。
install 時(shí) peerDependencies 不會(huì)被安裝,開發(fā)時(shí)一般會(huì)配合 devDependencies 來實(shí)現(xiàn)開發(fā)和發(fā)包時(shí)的版本解耦。
{
"peerDependencies": {
"react": "16 || 17 || 18"
},
"devDependencies": {
"react": "16"
}
}
復(fù)制代碼
定義在依賴中
install 時(shí) peerDependencies 不會(huì)安裝,但是包管理器會(huì)檢查項(xiàng)目的依賴與 peerDependencies 是否匹配,如果版本不匹配或未安裝,將會(huì)彈出警告。
包開發(fā)將依賴定義在 peerDependencies 中來避免項(xiàng)目中和依賴包中出現(xiàn)重復(fù)安裝包所導(dǎo)致的包版本不相容、打包了多份不同版本的庫(kù)等問題。
此外通過 peerDependenciesMeta 可以讓 peerDependencies 作為可選依賴項(xiàng),讓開發(fā)者可以有選擇性的選擇需要的包:
{
"peerDependenciesMeta": {
"soy-milk": {
"optional": true
}
}
}
復(fù)制代碼
optionalDependencies
optionalDependencies 用于定義可選依賴項(xiàng),和 dependencies 非常類似,主要的差別在于:在 optionalDependencies 中的依賴包安裝報(bào)錯(cuò)甚至找不到時(shí)不會(huì)影響到包管理器的安裝行為。
定義在項(xiàng)目中
install 時(shí)會(huì)被安裝,但是安裝失敗時(shí)不會(huì)中斷安裝行為,程序依舊可以正常運(yùn)行。項(xiàng)目中使用時(shí)應(yīng)該通過判定該包是否存在來決定所需要執(zhí)行的代碼。
定義在依賴中
install 時(shí)會(huì)被安裝,但是安裝失敗時(shí)不會(huì)中斷安裝行為,程序依舊可以正常運(yùn)行。
bundleDependencies/bundledDependencies
bundleDependencies 是一個(gè)較為特殊的依賴項(xiàng)定義,不同于其它依賴項(xiàng)定義,他的數(shù)據(jù)結(jié)構(gòu)是一個(gè)數(shù)組,需要配合 dependencies 使用。
{
"bundleDependencies": ["renderized", "super-streams"]
}
復(fù)制代碼
bundleDependencies 在項(xiàng)目中不起作用,在項(xiàng)目作為包發(fā)布時(shí)通過 npm pack,將會(huì)把 bundleDependencies 中的依賴包的本地代碼和該項(xiàng)目包一起打包成一個(gè)文件。
在 install 時(shí)通過 url 指定 pack 打包好的文件,將會(huì)將文件中打包的依賴解壓到包目錄,而不會(huì)去根據(jù) dependencies 中的定義去安裝 bundleDependencies 中的包。
總結(jié)
簡(jiǎn)單總結(jié)下所有依賴的安裝行為和使用場(chǎng)景:
| 依賴類型 | 定義在項(xiàng)目中 | 定義在依賴中 | 一句話總結(jié) | 舉例 |
dependencies |
會(huì)被安裝 | 會(huì)被安裝 | 定義包運(yùn)行所需要的依賴包 | 某前端項(xiàng)目使用 react 進(jìn)行開發(fā),需要將 react 添加到 dependencies 中 |
devDependencies |
會(huì)被安裝 | 不會(huì)被安裝 | 定義包在開發(fā)時(shí)所需要的依賴包 | antd 使用了 @testing-library/react 進(jìn)行測(cè)試,需要將 @testing-library/react 添加到 devDependencies 中 |
peerDependencies |
不會(huì)被安裝 | 不會(huì)被安裝,但是如果指向的依賴沒有被安裝或不符合時(shí)會(huì)有警告(peerDependenciesMeta 會(huì)影響該行為) |
定義該包運(yùn)行所需要的依賴環(huán)境,一般和 devDependencies 一起使用 |
antd 是一個(gè) react 組件庫(kù),為了不和使用它的項(xiàng)目中的 react 版本定義造成沖突,需要將支持的 react 版本添加到 peerDependencies 中 |
optionalDependencies |
會(huì)被安裝,但是安裝報(bào)錯(cuò)不會(huì)影響 | 會(huì)被安裝,但是安裝報(bào)錯(cuò)不會(huì)影響 | optionalDependencies 用于定義對(duì)包運(yùn)行不會(huì)造成影響的依賴包 |
一個(gè)包在使用 A 包進(jìn)行了某些操作,但是如果 A 包不在的話,可以使用別的 API 達(dá)到同樣的效果,可以將 A 包添加到 optionalDependencies 中 |
