亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

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

硬鏈接

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

不可以為目錄創(chuàng)建硬鏈接。因?yàn)檫@可能會(huì)造成循環(huán)引用的問題,假如目錄A硬鏈接到目錄B,而目錄B內(nèi)又包含了對目錄A的引用(可能是直接引用或者間接引用),那么就會(huì)形成一個(gè)循環(huán)。在遍歷目錄樹時(shí),系統(tǒng)可能會(huì)陷入這個(gè)無限循環(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值

軟鏈接(符號(hào)鏈接)

和原文件不是同一個(gè)文件,符號(hào)鏈接會(huì)有自己的inode,它所引用的是原文件的path,當(dāng)原文件被移動(dòng)或刪除的時(shí)候,符號(hào)鏈接的文件也會(huì)失效。例如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 的時(shí)候,如果 100 個(gè)項(xiàng)目都依賴 lodash,那么 lodash 很可能就被安裝了 100 次,磁盤中就有 100 個(gè)地方寫入了這部分代碼,這就會(huì)浪費(fèi)大量的磁盤空間。比較好的辦法就是每個(gè)包只在全局存儲(chǔ)一份,其它項(xiàng)目在使用時(shí)都通過引用去鏈接到這個(gè)包的地址,pnpm就是通過 內(nèi)部使用基于內(nèi)容尋址的文件系統(tǒng)來存儲(chǔ)磁盤上所有的文件來實(shí)現(xiàn)節(jié)省空間的。

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

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

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

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

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中唯一真實(shí)的文件。當(dāng)所有的依賴(包括依賴的子依賴)都硬鏈接到node_modules文件夾中的.pnpm目錄后就開始創(chuàng)建符號(hào)鏈接去構(gòu)建嵌套的依賴結(jié)構(gòu)。也就是在本例中的foo會(huì)依賴bar,那么就會(huì)在foo+@+版本號(hào)目錄下的node_modules目錄下創(chuàng)建bar依賴的符號(hào)鏈接去構(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 // 將嵌套依賴通過符號(hào)鏈接連接到真實(shí)的文件中

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

node_modules
├── foo --> ./.pnpm/foo@1.0.0/node_modules/foo 軟鏈接到.pnpm目錄下的真實(shí)文件
└── .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目錄中每個(gè)依賴包的目錄結(jié)構(gòu)都是固定的,每個(gè)依賴真實(shí)的文件(也就是該依賴的硬鏈接)都會(huì)放在一個(gè)包名+@+版本號(hào)的目錄的node_modules下,而該依賴的所有子依賴又通過符號(hào)鏈接放在同一層級下,這樣做的一個(gè)好處就是依賴包可以在代碼中引用自己。比如foo依賴包中的代碼中可以使用 const foo = require('foo') 這是沒問題的,因?yàn)閚ode查找依賴時(shí)就是通過node_modules一層一層去找到。

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

驗(yàn)證一下,根目錄的node_modules文件夾中項(xiàng)目的直接依賴包的符號(hào)鏈接是指向.pnpm中的真實(shí)文件的

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

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

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

依賴共享

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

依賴包的項(xiàng)目隔離

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

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

以上就是pnpm實(shí)現(xiàn)依賴包共享和依賴包項(xiàng)目隔離的方法詳解的詳細(xì)內(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)建一個(gè)目錄、創(chuàng)建一個(gè)文件、讀取文件內(nèi)容等都是我們開發(fā)中經(jīng)常需要用到的功能
    2022-09-09
  • Node交互式的SFTP上傳實(shí)現(xiàn)過程剖析

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

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

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

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

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

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

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

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

    Nodejs如何解決跨域(CORS)

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

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

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

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

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

    如何用nvm管理眾多nodejs版本詳細(xì)教程

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

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

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

最新評論