npm 存在的問題
我們經(jīng)常使用 npm
來管理 node 項(xiàng)目中的包,從 package.json
中讀取配置將依賴下載到本地,以保障項(xiàng)目的正常運(yùn)行。
當(dāng)項(xiàng)目數(shù)量多時(shí),這樣的包管理方式會(huì)非常的占用電腦內(nèi)存。由于每個(gè)項(xiàng)目都有屬于自己的依賴,每個(gè)項(xiàng)目都需要安裝,即使 npm 會(huì)對(duì)依賴進(jìn)行緩存,但是每個(gè)項(xiàng)目仍然需要安裝到自己的 node_modules
文件夾下,此時(shí)每個(gè)項(xiàng)目安裝的每一份依賴都會(huì)在磁盤中保存一份,即使各個(gè)項(xiàng)目中依賴的版本可能相同。
pnpm
就是針對(duì)以上問題出現(xiàn)的解決方案,它使用統(tǒng)一的倉庫來存放項(xiàng)目中的包,在項(xiàng)目中使用硬鏈接+軟連接的方式找到依賴所在磁盤的位置。
硬鏈接和軟連接
想要清晰的知道 pnpm 管理依賴的原理,首先要了解硬鏈接和軟連接、拷貝操作的區(qū)別。
拷貝操作會(huì)在磁盤中復(fù)制一份新的數(shù)據(jù)
,比如拷貝 a.js 為 a_copy.js,兩個(gè)文件在拷貝后就互不關(guān)聯(lián),修改 a.js 不會(huì)影響 a_copy.js,刪除 a_copy.js 也不會(huì)影響 a.js。
硬鏈接是通過尋址的方式
找到磁盤中的數(shù)據(jù),比如新建 b_hard.js 與 b.js 創(chuàng)建硬鏈接,兩者指向的是同一個(gè)磁盤數(shù)據(jù),所以修改其中一個(gè)文件,另一個(gè)文件也會(huì)發(fā)生變化。
軟連接就是我們平時(shí)常見的創(chuàng)建快捷方式
(文件后面會(huì)存在一個(gè)向右的小箭頭),它只是保存著文件的路徑,不可以編輯,直接雙擊就會(huì)找到原始的文件。如果原文件被刪除,通過軟連接將無法找到磁盤中的數(shù)據(jù)。
我們可以通過命令來進(jìn)行連接操作,windows 是這樣的
/*拷貝*/ copy a.js a_copy.js
/*硬鏈接*/ mklink /H b_hard.js b.js
/*軟連接*/ mklink c_soft.js c.js
pnpm原理
使用 npm 或者 yarn 時(shí),如果有100個(gè)項(xiàng)目,并且所有項(xiàng)目都有一個(gè)相同的依賴包,那么在磁盤上就需要保存100份該相同依賴的包
。
如果使用 pnpm,依賴包將被放在統(tǒng)一的位置,當(dāng)安裝包時(shí),其包含的所有文件會(huì)硬鏈接到這個(gè)位置,不會(huì)另外占用磁盤空間,這樣不同項(xiàng)目之間就可以共享相同版本的依賴。
如果對(duì)同一依賴包使用相同的版本
,那么磁盤上只有這個(gè)依賴包的一份文件,如果對(duì)同一依賴包使用不同的版本
,那么只有版本之間不同的文件
被存儲(chǔ)起來。
比如 a/b/c 三個(gè)項(xiàng)目都使用 axios,axios 的所有文件都保存在 pnpm 上,axios 這些文件對(duì)應(yīng)著磁盤的數(shù)據(jù),直接 a/b/c 項(xiàng)目的axios 通過硬鏈接指向磁盤里的數(shù)據(jù)。 這樣有兩個(gè)好處:
(1)效率非常高,無需下載、查找緩存解壓等操作
(2)節(jié)省磁盤空間,每個(gè)項(xiàng)目不需要再下載一份
pnpm 依賴包統(tǒng)一保存的位置可以使用命令 pnpm store path
來查看
非扁平的 node_modules 目錄
使用 npm 或者 yarn安裝的依賴包會(huì)將所有的子級(jí)依賴全部平鋪
到 node_modules 文件夾中,即扁平化的目錄結(jié)構(gòu),這樣會(huì)導(dǎo)致源碼可以訪問本來不屬于當(dāng)前項(xiàng)目所設(shè)定的依賴包。
比如安裝 axios ,同時(shí)會(huì)安裝非常多的其它的庫如 form-data,雖然在 package.json 中是沒有配置的,但在源代碼中可以直接通過require('form-data') 引用
,這樣就會(huì)有隱患,如果項(xiàng)目某天刪除了 axios,form-data 就不存在了。
使用 npm 和 pnpm 分別只安裝 axios,npm 會(huì)將 axios 所需的其它依賴平鋪,而 pnpm 的 node_modules 根目錄下只有 axios 和 .pnpm 文件夾,這樣就可以避免非主動(dòng)下載的其它依賴包可隨意訪問的情況。
如果直接按照這樣的層級(jí)下載包,可能會(huì)帶來新的問題,如多個(gè)包依賴同一個(gè)包時(shí),就會(huì)被重復(fù)安裝。
? node_modules
? axios
? node_modules
? form-data
? xxx
? node_modules
? form-data
那 pnpm 是如何做到非扁平化并且不重復(fù)安裝的呢?答案就是它使用硬鏈接與軟連接結(jié)合的方式來與依賴包關(guān)聯(lián)。
在 node_modules 根目錄有一個(gè)文件夾 .pnpm,這里包含了項(xiàng)目所有依賴。
根目錄下 axios 軟連接
到 .pnpm 目錄下的 axios 文件夾中,展開 .pnpm/axios@16.1 的node_modules 文件夾,其中有 axios 所需的依賴,包含 axios、follow-redirects、form-data、proxy-from-env,其中 axios 硬鏈接
到磁盤中(即與 pnpm 倉庫保存的地址一致),其它文件軟連接到 .pnpm 的自身位置。
文章來源:http://www.zghlxwxcb.cn/news/detail-746579.html
node_modules 根目錄下的依賴
,軟連接到 .pnpm 文件夾中,如果有相互依賴的關(guān)系,仍然通過軟連接,只有找到依賴自身,才會(huì)通過硬鏈接找到磁盤中的位置,這樣可以保證同一個(gè)項(xiàng)目里不同依賴也不會(huì)重復(fù)安裝,同時(shí)不同項(xiàng)目之間的相同依賴也無需在磁盤中存儲(chǔ)多份。文章來源地址http://www.zghlxwxcb.cn/news/detail-746579.html
到了這里,關(guān)于pnpm 管理依賴包是如何節(jié)省磁盤空間的?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!