欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

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

硬鏈接

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

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

如何創(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,當原文件被移動或刪除的時候,符號鏈接的文件也會失效。例如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 個地方寫入了這部分代碼,這就會浪費大量的磁盤空間。比較好的辦法就是每個包只在全局存儲一份,其它項目在使用時都通過引用去鏈接到這個包的地址,pnpm就是通過 內(nèi)部使用基于內(nèi)容尋址的文件系統(tǒng)來存儲磁盤上所有的文件來實現(xiàn)節(jié)省空間的。

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

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

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

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

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中唯一真實的文件。當所有的依賴(包括依賴的子依賴)都硬鏈接到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文件夾中只存在項目的直接依賴包的符號鏈接,當項目中的代碼使用這個包時會根據(jù)符號鏈接引用的地址找到.pnpm目錄中的真實文件。

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

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

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

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

依賴共享

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

依賴包的項目隔離

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

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

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

相關(guān)文章

  • Node.js?操作本地文件及深入了解fs內(nèi)置模塊

    Node.js?操作本地文件及深入了解fs內(nèi)置模塊

    這篇文章主要介紹了Node.js?操作本地文件及深入了解fs內(nèi)置模塊,node.js作為服務(wù)端應(yīng)用,肯定少不了對本地文件的操作,像創(chuàng)建一個目錄、創(chuàng)建一個文件、讀取文件內(nèi)容等都是我們開發(fā)中經(jīng)常需要用到的功能
    2022-09-09
  • Node交互式的SFTP上傳實現(xiàn)過程剖析

    Node交互式的SFTP上傳實現(xiàn)過程剖析

    這篇文章主要為大家介紹了Node交互式的SFTP上傳實現(xiàn)過程剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 輕松創(chuàng)建nodejs服務(wù)器(9):實現(xiàn)非阻塞操作

    輕松創(chuàng)建nodejs服務(wù)器(9):實現(xiàn)非阻塞操作

    這篇文章主要介紹了輕松創(chuàng)建nodejs服務(wù)器(9):實現(xiàn)非阻塞操作,本系列文章會教你一步一步創(chuàng)建一個完整的服務(wù)器,要的朋友可以參考下
    2014-12-12
  • 詳解node中創(chuàng)建服務(wù)進程

    詳解node中創(chuàng)建服務(wù)進程

    本篇文章主要介紹了詳解node中創(chuàng)建服務(wù)進程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Node.js本地搭建簡單頁面小游戲的過程

    Node.js本地搭建簡單頁面小游戲的過程

    Node.js是能夠在服務(wù)器端運行 JavaScript 的開放源代碼、跨平臺運行環(huán)境,Node.js 大部分基本模塊都用 JavaScript 語言編寫,下面將介紹如何簡單幾步實現(xiàn)遠程公共網(wǎng)絡(luò)下訪問windwos node.js的服務(wù)端
    2024-01-01
  • Nodejs如何解決跨域(CORS)

    Nodejs如何解決跨域(CORS)

    這篇文章主要介紹了Nodejs如何解決跨域(CORS)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 基于Node實現(xiàn)可以操作MySQL的接口

    基于Node實現(xiàn)可以操作MySQL的接口

    這篇文章主要介紹了用Node寫個可以操作MySQL的接口,以前也用Node寫過接口,但不涉及數(shù)據(jù)庫操作,而我們發(fā)現(xiàn),后端寫接口,基本都繞不開數(shù)據(jù)庫操作,感覺不寫一個能操作數(shù)據(jù)庫的接口,就不算真正意義上學會了寫接口,那我們今天就學習一下,如何寫一個可以操作數(shù)據(jù)庫的接口
    2024-05-05
  • 深入解析koa之異步回調(diào)處理

    深入解析koa之異步回調(diào)處理

    這篇文章主要介紹了深入解析koa之異步回調(diào)處理,我們研究一下koa當中異步回調(diào)同步化寫法的原理,同樣的,我們也會實現(xiàn)一個管理函數(shù),是的我們能夠通過同步化的寫法來寫異步回調(diào)函數(shù)。,需要的朋友可以參考下
    2019-06-06
  • 如何用nvm管理眾多nodejs版本詳細教程

    如何用nvm管理眾多nodejs版本詳細教程

    NVM是一個nodejs的版本管理工具,nvm和n都是node.js版本管理工具,為了解決node.js各種版本存在不兼容現(xiàn)象可以通過它可以安裝和切換不同版本的 node.js,這篇文章主要介紹了如何用nvm管理眾多nodejs版本的相關(guān)資料,需要的朋友可以參考下
    2025-04-04
  • npm?list輸出結(jié)果包含extraneous標志記錄分析

    npm?list輸出結(jié)果包含extraneous標志記錄分析

    這篇文章主要為大家介紹了npm?list輸出結(jié)果包含extraneous標志記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01

最新評論