JavaScript常見(jiàn)面試題:npm跟pnpm有什么區(qū)別叛薯?

npm的發(fā)展

最早期的npm

早期的npm的依賴(lài)會(huì)被嵌套安裝响鹃,也就是說(shuō):

{
  "dependencies": {
    "A": "^1.0",
    "B": "^1.0",
    "C": "^1.0"
  }
}

如果我A,B,C三個(gè)包均引用了D包,但是A案训、B引用的是D@1.0.0,而C引用的是D@2.0.0粪糙,他們會(huì)分別安裝到自己的node_modules底下强霎。

// 項(xiàng)目的根node_modules
node_modules
     A
           node_modules
                  D@1.0.0
     B
           node_modules
                  D@1.0.0
     C
           node_modules
                  D@2.0.0

但是這樣會(huì)導(dǎo)致依賴(lài)地獄。會(huì)出現(xiàn)依賴(lài)路徑過(guò)長(zhǎng)蓉冈、以及文件被多次復(fù)制的問(wèn)題城舞!

npm3

為了解決依賴(lài)路徑過(guò)長(zhǎng)的問(wèn)題,在npm3之后寞酿,依賴(lài)就被扁平化管理了家夺。依賴(lài)被頂?shù)搅隧攲樱钱?dāng)出現(xiàn)上面的情況的時(shí)候伐弹,依賴(lài)的表現(xiàn)是怎么樣的拉馋?

這時(shí)候先安裝的包,會(huì)把他依賴(lài)的相應(yīng)版本提前惨好,后面安裝的D包如果版本跟被置頂?shù)陌姹咎?hào)不一致煌茴,會(huì)被安裝到其node_modules下。

// 項(xiàng)目的根node_modules
node_modules
     A
     B
     C
           node_modules
                  D@2.0.0
     D(@1.0.0 )

但是這個(gè)會(huì)出現(xiàn)一個(gè)問(wèn)題日川,就是如果根據(jù)安裝的順序進(jìn)行依賴(lài)提升蔓腐,用戶在npm i的時(shí)候,得到的結(jié)果是不確定的龄句。因?yàn)閚pm也做了相對(duì)應(yīng)的優(yōu)化回论,把引用次數(shù)多的包扁平化管理散罕,但當(dāng)兩個(gè)引用次數(shù)一樣的時(shí)候,那必然帶來(lái)的不確定性

npm5

為了解決上面的問(wèn)題傀蓉,在package.json的基礎(chǔ)上欧漱,又新增了 package-lock.json 文件。

雖然v5.0.x跟v5.1.0的版本不一樣僚害,我們無(wú)需記住這個(gè)硫椰,只需要稍微了解即可。

  • npm@5.0.x 里萨蚕,不管package.json怎么變靶草,npm i都會(huì)根據(jù)lock文件下載。

  • npm@5.1.0版本后岳遥,npm i會(huì)無(wú)視package-lock.json文件奕翔,直接下載新的npm包;

  • npm@5.4.2版本后浩蓉,如果package.json和package.lock文件不同那么派继,npm i時(shí)會(huì)根據(jù)package的版本進(jìn)行下載并更新package-lock;如果兩個(gè)文件相同則會(huì)根據(jù)package-lock文件下載捻艳,不管package有無(wú)更新

但是盡管這樣驾窟,他會(huì)有幽靈依賴(lài)的問(wèn)題。

幽靈依賴(lài)

幽靈依賴(lài)在npm@3.x的版本中就已經(jīng)出現(xiàn)了认轨,因?yàn)橛辛颂嵘奶匦陨鹇纾鲜隼又校m然項(xiàng)目中沒(méi)有在package.json中顯性聲明要安裝D@1.0.0嘁字,但是npm已經(jīng)將他提升到根部恩急,此時(shí)在項(xiàng)目中引用D并進(jìn)行使用是不會(huì)報(bào)錯(cuò)的。但是由于我們沒(méi)有顯性聲明纪蜒,假如一旦依賴(lài)A不再依賴(lài)D或者版本有變化那么此時(shí)install后代碼就會(huì)因?yàn)檎也坏揭蕾?lài)而報(bào)錯(cuò)V怨А!纯续!

當(dāng)然随珠,npm還有另一個(gè)問(wèn)題,就是依賴(lài)分身杆烁。比如我們A,B引用的是D@1.0.0牙丽,而C,E引用的是D@2.0.0,項(xiàng)目中D@1.0.0已經(jīng)被依賴(lài)提升到頂部了兔魂,那么C,E的node_modules種均會(huì)有 D@2.0.0 的依賴(lài)烤芦,因此他會(huì)被重復(fù)安裝。

pnpm

pnpm 號(hào)稱(chēng) performance npm析校,與npm的依賴(lài)提升和扁平化不同构罗。pnpm采取了一套新的策略:內(nèi)容尋址儲(chǔ)存铜涉;

還是使用上面的例子: 項(xiàng)目依賴(lài)了A、B遂唧、C芙代,之后A依賴(lài)D@1.0,B依賴(lài)D@2.0盖彭,而C也依賴(lài)D@1.0纹烹,使用 pnpm 安裝依賴(lài)后 node_modules 結(jié)構(gòu)如下

// 項(xiàng)目的根node_modules
node_modules
     .pnpm
           A@1.0.0
                  node_modules
                       A => <store>/A@1.0.0
                       D => ../../D@1.0.0
           D@1.0.0
                  node_modules
                        D => <store>/D@1.0.0
           B@1.0.0
                  node_modules
                       B => <store>/B@1.0.0
                       D => ../../D@2.0.0
           C@1.0.0
                node_modules
                     C => <store>/C@1.0.0
                     D => ../../D@1.0.0
      A => .pnpm/A@1.0.0/node_modules/A
      B => .pnpm/B@1.0.0/node_modules/B
      C => .pnpm/C@1.0.0/node_modules/C

我們看到,pnpm擁有自己的.pnpm目錄召边,他會(huì)以平鋪的方式來(lái)存儲(chǔ)所有包铺呵,以依賴(lài)名加上版本號(hào)的名字為命名,實(shí)現(xiàn)了版本的復(fù)用隧熙。而且他不是通過(guò)拷貝機(jī)器緩存中的依賴(lài)到項(xiàng)目目錄下片挂,而是通過(guò)硬鏈接的方式,這能減少空間占用贞盯。

至于根目錄下用于項(xiàng)目使用的依賴(lài)音念,則是通過(guò)符號(hào)鏈接的方式,鏈接到它的 .pnpm 目錄下的對(duì)應(yīng)位置躏敢。

shamefully-hosit

默認(rèn)情況下闷愤,通過(guò)pnpm的node_modules你只能訪問(wèn)到在 package.json 文件中聲明的依賴(lài),只有依賴(lài)項(xiàng)才能訪問(wèn)未聲明的依賴(lài)項(xiàng)件余。你可能需要需要再.npmrc文件中聲明了 shamefully-host=true肝谭,他才會(huì)像npm平鋪的方式,我們才能使用package.json沒(méi)有顯性聲明的幽靈依賴(lài)蛾扇。

不過(guò)事實(shí)上,pnpm的嚴(yán)格模式能夠幫助我們避免一些低級(jí)錯(cuò)誤魏滚。正常情況下镀首,是不推薦使用羞恥提升的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鼠次,一起剝皮案震驚了整個(gè)濱河市更哄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腥寇,老刑警劉巖成翩,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異赦役,居然都是意外死亡麻敌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)掂摔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)术羔,“玉大人赢赊,你說(shuō)我怎么就攤上這事〖独” “怎么了释移?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)寥殖。 經(jīng)常有香客問(wèn)我玩讳,道長(zhǎng),這世上最難降的妖魔是什么嚼贡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任熏纯,我火速辦了婚禮,結(jié)果婚禮上编曼,老公的妹妹穿的比我還像新娘豆巨。我一直安慰自己,他們只是感情好掐场,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布往扔。 她就那樣靜靜地躺著,像睡著了一般熊户。 火紅的嫁衣襯著肌膚如雪萍膛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天嚷堡,我揣著相機(jī)與錄音蝗罗,去河邊找鬼。 笑死蝌戒,一個(gè)胖子當(dāng)著我的面吹牛串塑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播北苟,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼桩匪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了友鼻?” 一聲冷哼從身側(cè)響起傻昙,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彩扔,沒(méi)想到半個(gè)月后妆档,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虫碉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年贾惦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纤虽,死狀恐怖乳绕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逼纸,我是刑警寧澤洋措,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站杰刽,受9級(jí)特大地震影響菠发,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贺嫂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一滓鸠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧第喳,春花似錦糜俗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至扩淀,卻和暖如春楔敌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背驻谆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工卵凑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胜臊。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓勺卢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親象对。 傳聞我的和親對(duì)象是個(gè)殘疾皇子值漫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容