最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

pnpm實現(xiàn)依賴包共享和依賴包項目隔離的方法詳解

 更新時間:2024年05月09日 15:24:55   作者:cv攻城獅_  
pnpm是Node.js的包管理器,它是 npm 的直接替代品,相對于npm和yarn它的優(yōu)點(diǎn)就在于速度快和高效節(jié)省磁盤空間,本文主要講解pnpm相比于npm/yarn如何利用軟硬鏈接來節(jié)省磁盤空間,以及如何實現(xiàn)依賴包共享和依賴包項目隔離的,需要的朋友可以參考下

前言

pnpm(performant npm,意思是高性能的 npm)是 Node.js 的包管理器。它是 npm 的直接替代品,相對于npm和yarn它的優(yōu)點(diǎn)就在于速度快高效節(jié)省磁盤空間

本文主要講解pnpm相比于npm/yarn如何利用軟硬鏈接來節(jié)省磁盤空間,以及如何實現(xiàn)依賴包共享和依賴包項目隔離的。

硬鏈接

只能引用同一文件系統(tǒng)中的文件。硬鏈接引用的是文件在文件系統(tǒng)中的 物理索引(inode) 而inode存儲了文件的元數(shù)據(jù)和指向文件數(shù)據(jù)的指針。當(dāng)移動或者刪除原始文件時,硬鏈接不會被破壞,因為它所引用的是文件的inode而不是文件在文件結(jié)構(gòu)中的位置,刪除或移動原始文件只是改變了文件的結(jié)構(gòu)。硬鏈接記錄的是目標(biāo)的inode。同一文件的不同硬鏈接文件相當(dāng)于該文件的多個不同文件名,即多個不同訪問路徑,他們的inode都是一樣的。刪除一個硬鏈接并不會刪除文件的數(shù)據(jù),除非這是指向該文件的最后一個硬鏈接。只有當(dāng)所有指向文件的硬鏈接都被刪除后,該文件才會被標(biāo)記為可以刪除,并在適當(dāng)?shù)臅r候被文件系統(tǒng)清理。

不可以為目錄創(chuàng)建硬鏈接。因為這可能會造成循環(huán)引用的問題,假如目錄A硬鏈接到目錄B,而目錄B內(nèi)又包含了對目錄A的引用(可能是直接引用或者間接引用),那么就會形成一個循環(huán)。在遍歷目錄樹時,系統(tǒng)可能會陷入這個無限循環(huán)中,導(dǎo)致無法正確定位到要訪問的目錄。

如何創(chuàng)建硬鏈接呢?

// 初始文件為file
ln file hardfile // linux環(huán)境下創(chuàng)建file文件的硬鏈接
ln -ls // 查看文件信息

可以看到硬鏈接的文件和原始文件的inode值相同。

刪除原始文件后還可以訪問硬鏈接的文件:

rm file
cat hardfile // 查看文件內(nèi)容
ls -li 查看該文件夾下所有文件的inode值

軟鏈接(符號鏈接)

和原文件不是同一個文件,符號鏈接會有自己的inode,它所引用的是原文件的path,當(dāng)原文件被移動或刪除的時候,符號鏈接的文件也會失效。例如windows中的快捷方式就是一種軟鏈接。也可以為目錄創(chuàng)建軟連接。

ln -s file sysfile // linux環(huán)境下創(chuàng)建file文件的軟連接
ls -li

可以看到軟連接文件跟原始文件的inode值不同。

刪除原始文件后不能訪問軟鏈接的文件:

rm file
cat sysfile

高效的節(jié)省磁盤空間

npm和yarn存在的問題

用 npm/yarn 的時候,如果 100 個項目都依賴 lodash,那么 lodash 很可能就被安裝了 100 次,磁盤中就有 100 個地方寫入了這部分代碼,這就會浪費(fèi)大量的磁盤空間。比較好的辦法就是每個包只在全局存儲一份,其它項目在使用時都通過引用去鏈接到這個包的地址,pnpm就是通過 內(nèi)部使用基于內(nèi)容尋址的文件系統(tǒng)來存儲磁盤上所有的文件來實現(xiàn)節(jié)省空間的。

pnpm安裝依賴結(jié)構(gòu)

我們借助pnpm官方給的例子進(jìn)行講解。假如我們的項目依賴了foo包,而foo包又依賴了bar包,那使用pnpm i的整個安裝流程是怎樣的,node_modules目錄的結(jié)構(gòu)又是怎樣的?

當(dāng)執(zhí)行pnpm i后首先會將依賴包下載到pnpm配置的本地倉庫里邊,可以使用pnpm config get store-dir命令查看,默認(rèn)是在用戶主文件夾中,可以通過pnpm config set store-dir ×××來手動設(shè)置包下載后存放的目錄。下載到本地倉庫后,會在項目中的node_modules文件夾中創(chuàng)建一個 .pnpm 文件夾,這個文件夾會將所有的依賴以及依賴的子依賴鋪平通過硬鏈接的方式引入進(jìn)來

-> 表示硬鏈接 --> 表示符號鏈接(軟鏈接)

node_modules
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       └── bar -> <store-dir>/bar  // 硬鏈接到本地store-dir倉庫中的bar文件
    │           ├── index.js
    │           └── package.json
    └── foo@1.0.0
        └── node_modules
            └── foo -> <store-dir>/foo // 硬鏈接到本地store-dir倉庫中的foo文件
                ├── index.js
                └── package.json

它們是node_modules中唯一真實的文件。當(dāng)所有的依賴(包括依賴的子依賴)都硬鏈接到node_modules文件夾中的.pnpm目錄后就開始創(chuàng)建符號鏈接去構(gòu)建嵌套的依賴結(jié)構(gòu)。也就是在本例中的foo會依賴bar,那么就會在foo+@+版本號目錄下的node_modules目錄下創(chuàng)建bar依賴的符號鏈接去構(gòu)建嵌套結(jié)構(gòu)。

node_modules
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       └── bar -> <store-dir>/bar
    └── foo@1.0.0
        └── node_modules
            ├── foo -> <store-dir>/foo
            └── bar --> ../../bar@1.0.0/node_modules/bar // 將嵌套依賴通過符號鏈接連接到真實的文件中

接下來就是去處理項目的直接依賴關(guān)系了,比如本例項目直接依賴了foo包

node_modules
├── foo --> ./.pnpm/foo@1.0.0/node_modules/foo 軟鏈接到.pnpm目錄下的真實文件
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       └── bar -> <store-dir>/bar
    └── foo@1.0.0
        └── node_modules
            ├── foo -> <store-dir>/foo
            └── bar --> ../../bar@1.0.0/node_modules/bar

可以看到.pnpm目錄中每個依賴包的目錄結(jié)構(gòu)都是固定的,每個依賴真實的文件(也就是該依賴的硬鏈接)都會放在一個包名+@+版本號的目錄的node_modules下,而該依賴的所有子依賴又通過符號鏈接放在同一層級下,這樣做的一個好處就是依賴包可以在代碼中引用自己。比如foo依賴包中的代碼中可以使用 const foo = require('foo') 這是沒問題的,因為node查找依賴時就是通過node_modules一層一層去找到。

這種目錄結(jié)構(gòu)的另一個好處就是可以避免npm/yarn存在的幽靈依賴問題,在根目錄的node_modules文件夾中只存在項目的直接依賴包的符號鏈接,當(dāng)項目中的代碼使用這個包時會根據(jù)符號鏈接引用的地址找到.pnpm目錄中的真實文件。

驗證一下,根目錄的node_modules文件夾中項目的直接依賴包的符號鏈接是指向.pnpm中的真實文件的

拿express包舉例,我們先在.pnpm目錄中找到express包的真實文件,然后再添加一行打印語句,那么當(dāng)根目錄的node_modules文件夾中express的符號鏈接中的文件也相應(yīng)改變就可以驗證上面的結(jié)論。

express文件夾后邊的一個箭頭符號就表示該文件夾是一個符號鏈接,其實就是真實文件的一個快捷方式,當(dāng)真實文件里邊的內(nèi)容改變了,快捷方式內(nèi)的文件內(nèi)容肯定也跟著改變了。

因為pnpm是通過硬鏈接和符號鏈接去管理node_modules文件夾的,而不是像npm和yarn那樣直接將依賴包復(fù)制到node_modules中,所以可以高效的節(jié)省磁盤空間。

依賴共享

因為pnpm再安裝依賴包時是全局倉庫store-dir內(nèi)依賴包一個硬鏈接,那么其它的項目也都是對全局依賴中原始依賴包的一個硬鏈接,真實的文件只在磁盤中保留了一份,避免了多個項目帶來多份相同文件引起的空間浪費(fèi)問題。這就是多個項目中的依賴共享。

依賴包的項目隔離

但是說到硬鏈接,又有一個問題,這相當(dāng)于所有項目都依賴了同一個原始文件,那么在一個項目中修改了某個npm包的文件,就會影響到其他項目。但是我自己試了一下,開了兩個項目都依賴了express包,再其中一個項目修改后并不會影響到另外一個項目。經(jīng)過查閱,pnpm是使用了copy-on-write策略來解決這個問題的,實現(xiàn)依賴包的項目隔離。

copy-on-write(寫時復(fù)制)是一種優(yōu)化策略。這種策略的核心思想是在首次安裝或更新包時,盡量使用硬鏈接和符號鏈接來引用全局存儲庫(store-dir)中的文件,以節(jié)省磁盤空間和提高安裝速度。但是,當(dāng)需要修改某個文件時(例如,需要打log去調(diào)試依賴包中的文件),pnpm不會直接修改硬鏈接或符號鏈接引用的原始文件,而是會創(chuàng)建一個該文件的副本,并將這個副本放入項目的node_modules目錄中,相當(dāng)于修改的是原始文件的副本。這種做法的好處是避免了多個項目之間因為共享文件而產(chǎn)生的潛在沖突。每個項目都有其自己的node_modules目錄,其中包含它需要的所有依賴項和可能的文件副本,這些副本是獨(dú)立于其他項目的。這樣,即使一個項目更新了某個包,也不會影響到其他項目。

以上就是pnpm實現(xiàn)依賴包共享和依賴包項目隔離的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于pnpm依賴包隔離和共享的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Node.js使用gm拼裝sprite圖片

    Node.js使用gm拼裝sprite圖片

    這篇文章主要介紹了Node.js使用gm拼裝sprite圖片的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • nodejs搭建本地服務(wù)器并訪問文件操作示例

    nodejs搭建本地服務(wù)器并訪問文件操作示例

    這篇文章主要介紹了nodejs搭建本地服務(wù)器并訪問文件操作,結(jié)合實例形式分析了nodejs搭建本地服務(wù)器操作步驟及文件訪問相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2019-05-05
  • 參考?EventEmitter實現(xiàn)一個簡單的訂閱發(fā)布功能函數(shù)

    參考?EventEmitter實現(xiàn)一個簡單的訂閱發(fā)布功能函數(shù)

    這篇文章主要為大家介紹了參考?EventEmitter實現(xiàn)一個簡單的訂閱發(fā)布功能函數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 學(xué)習(xí)使用ExpressJS 4.0中的新Router的用法

    學(xué)習(xí)使用ExpressJS 4.0中的新Router的用法

    ExpressJS 4.0中提出了新的路由Router,提供了路由應(yīng)有的API,本文詳細(xì)的介紹了ExpressJS 4.0中的新Router的用法,非常具有實用價值,需要的朋友可以參考下
    2018-11-11
  • Express.js 全局錯誤處理實現(xiàn)

    Express.js 全局錯誤處理實現(xiàn)

    本文主要介紹了Express.js 全局錯誤處理實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 利用python分析access日志的方法

    利用python分析access日志的方法

    最近在自學(xué)python,光看是不行的,還是要多實操的。這就是一個寫給自己的小小工具。主要功能是,便利日志文件夾下的文件,根據(jù)設(shè)定的關(guān)鍵字查找是否有web攻擊行為。有需要的朋友們下面來一起看看吧。
    2016-10-10
  • Node.js實戰(zhàn)之Buffer和Stream模塊系統(tǒng)深入剖析詳解

    Node.js實戰(zhàn)之Buffer和Stream模塊系統(tǒng)深入剖析詳解

    這篇文章主要介紹了Node.js實戰(zhàn)之Buffer和Stream模塊系統(tǒng)深入剖析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • windows下安裝nodejs及框架express

    windows下安裝nodejs及框架express

    express是一個開源的node.js框架,初學(xué)者使用express可以快速的搭建一個Web項目,express中已經(jīng)集成了Web的http服務(wù)器創(chuàng)建、請求和文件管理以及Session的處理等功能,所以express是非常適合初學(xué)者的入門學(xué)習(xí),這篇文章通過兩種方式介紹windows下安裝nodejs及框架express
    2015-08-08
  • Node.js中MongoDB插入數(shù)據(jù)的實現(xiàn)方法

    Node.js中MongoDB插入數(shù)據(jù)的實現(xiàn)方法

    在Node.js中,可以使用MongoDB原生驅(qū)動或Mongoose庫來連接和操作MongoDB數(shù)據(jù)庫,本文就來介紹一下Node.js中MongoDB插入數(shù)據(jù)的實現(xiàn)方法,感興趣的可以了解一下
    2023-12-12
  • node終端里如何連接mysql數(shù)據(jù)庫并進(jìn)行sql查詢

    node終端里如何連接mysql數(shù)據(jù)庫并進(jìn)行sql查詢

    這篇文章主要為大家介紹了node終端里如何連接mysql數(shù)據(jù)庫并進(jìn)行sql查詢,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評論

曲沃县| 太仓市| 如东县| 察隅县| 东丽区| 宁明县| 江山市| 阜宁县| 金山区| 孙吴县| 平乡县| 夏河县| 视频| 福建省| 美姑县| 开平市| 成武县| 张掖市| 石景山区| 内黄县| 湖南省| 贵德县| 托克逊县| 广河县| 孟州市| 抚宁县| 屏山县| 南靖县| 甘谷县| 泌阳县| 松阳县| 渭源县| 巴彦县| 关岭| 洪洞县| 聊城市| 获嘉县| 青海省| 永吉县| 曲阜市| 开化县|