摘要:以及的不同之處原文譯者我并不是一個(gè)包管理器的專家。因此如果一年后我運(yùn)行,會(huì)安裝版本號(hào)為的最新版本的。這會(huì)導(dǎo)致循環(huán)依賴以及增加了版本不匹配的可能。從我目前收集的來(lái)看,的最初的主要目的是針對(duì)由于之前章節(jié)提及的相關(guān)行為導(dǎo)致的安裝的不確定性。
npm, yarn以及pnpm的不同之處
原文:Overview of differences between npm, yarn and pnpm
譯者:neal1991
welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me
LICENSE: MIT
我并不是一個(gè)包管理器的專家。相反,直到最近我才意識(shí)到npm使用的是本地的緩存。在不知道這個(gè)時(shí)候,我寫了這篇名為我的天--NPM克隆終于有意義了并且給出了一些我的不正確的猜想。這些反饋迫使我回頭并且重新審視近來(lái)這些包管理器的區(qū)別。
我在過(guò)去的5年時(shí)間一直都是使用npm。我也折騰了下yarn當(dāng)它第一次出來(lái)的時(shí)候,而且我是通過(guò)一個(gè)禮拜前的文章“為什么我們應(yīng)該使用pnpm”來(lái)學(xué)習(xí)pnpm的。
過(guò)去的一周,我一直花時(shí)間閱讀npm,yarn以及pnpm相關(guān)的東西,想總結(jié)一下然后分享我的發(fā)現(xiàn)。我的目標(biāo)讀者是長(zhǎng)期的npm用戶,并且不愿意花費(fèi)太多的時(shí)間了解有多少種npm的替代品,比如我自己。我只會(huì)關(guān)注這三種最常提及的(對(duì)于我)并且不會(huì)包括:ied,npm-install以及npmd,因?yàn)閷?duì)于它們我是一無(wú)所知。
還有重要的一點(diǎn)需要指出,直到寫這篇文章的時(shí)候,還沒(méi)有一個(gè)具有競(jìng)爭(zhēng)力的庫(kù)的目標(biāo)是替換NPM的registry(就是存儲(chǔ)包的地方),它們的目的都是替換npm命令行客戶端,提供另外一個(gè)可用的用戶界面以及行為,并且其功能也是類似的。
NPMnpm自從Node.js出現(xiàn)的那一天就存在了并且也是造成Node.js這個(gè)項(xiàng)目如此成功的原因之一。npm團(tuán)隊(duì)在讓npm保持向后兼容以及在多種環(huán)境下持續(xù)工作都做了很多的工作。
npm的設(shè)計(jì)理念是根據(jù) Semantic Versioning (semver),這是一個(gè)相當(dāng)直白的方法可以從他們官網(wǎng)的引用可以看出來(lái)。
給定一個(gè)版本號(hào)MAJOR.MINOR.PATCH,增量修改表示:
MAJOR版本修改意味著你做出了不兼容的API變化。
MINOR版本意味著你以向后兼容的方式增加了功能。
PATCH版本意味著你做出了向后兼容的bug修復(fù)。
npm使用一個(gè)叫做package.json的文件,用戶可以存儲(chǔ)項(xiàng)目的所有依賴通過(guò)運(yùn)行npm install --save。
例如,運(yùn)行npm install --save loadsh將會(huì)將這一條加入到package.json之中。
"dependencies": { "loadsh": "^4.17.4" }
注意^這個(gè)loadsh版本號(hào)之前的符號(hào)。這個(gè)符號(hào)告訴npm安裝任何與MAJOR版本相同的包。因此如果一年后我運(yùn)行npm install,npm會(huì)安裝MAJOR版本號(hào)為4的最新版本的loadsh。例如,它可以是loadsh@4.25.5(@是一個(gè)npm慣例用來(lái)指定包名的版本)。你可以在這看到所有支持的符號(hào): https://docs.npmjs.com/misc/semver。
這樣做的原因是,因?yàn)镸INOR版本的變動(dòng)(理論上)應(yīng)該只是包含向后兼容的濱化。因此安裝最新版本的包可能會(huì)引入重要的bug或者安全問(wèn)題,因?yàn)樽畛醢惭b的版本是4.17.4。
另一方面,它可能會(huì)導(dǎo)致多個(gè)開(kāi)發(fā)者的機(jī)器上安裝了不同版本的包,即使他們是共享同一個(gè)package.json文件,這樣會(huì)潛在地導(dǎo)致難以調(diào)試以及“在我的機(jī)器是好的啊”的情形。
大多數(shù)npm包都非常依賴其它的npm包。這會(huì)導(dǎo)致循環(huán)依賴以及增加了版本不匹配的可能。
可以通過(guò)npm config set save-exact true命令來(lái)關(guān)閉在包的版本前添加^的默認(rèn)行為,但這個(gè)只會(huì)鎖住高層次的依賴。因?yàn)槊恳粋€(gè)引入的包都有它們自己的package.json文件,在這里面的依賴可能包含了^,沒(méi)有辦法通過(guò)package.json來(lái)保證嵌套的內(nèi)容。
為了解決這個(gè)問(wèn)題,npm提供了一個(gè)shrinkwrap命令。這個(gè)命令能夠生成一個(gè)npm-shrinkwrap.json文件,對(duì)于所有的包以及嵌套的依賴規(guī)定了明確的版本。
這也就是說(shuō),即使是通過(guò)npm-shrinkwrap.json這個(gè)文件,npm也只是鎖住了包的版本而不是包的內(nèi)容。即使npm現(xiàn)在阻止用戶多次發(fā)布相同版本的包,npm管理依然有權(quán)利強(qiáng)制更新某些包。
下面是 shrinkwrap文檔頁(yè)面的引用:
如果你希望鎖定包內(nèi)包含的指定字節(jié),例如你有百分之百的信心能夠重新發(fā)布或者構(gòu)建,那么你應(yīng)該將你的依賴檢查到源代碼控制中,或者追求其它的某種能夠驗(yàn)證內(nèi)容而不是版本的機(jī)制。
npm version 2過(guò)去式對(duì)于每個(gè)包內(nèi)所有引入的依賴全部都安裝。如果已有一個(gè)項(xiàng)目,這個(gè)項(xiàng)目引入項(xiàng)目A,項(xiàng)目A引入項(xiàng)目B,項(xiàng)目B引入項(xiàng)目C,那么這個(gè)所有依賴的結(jié)構(gòu)樹看起來(lái)會(huì)是下面這樣:
node_modules - package-A -- node_modules --- package-B ----- node_modules ------ package-C -------- some-really-really-really-long-file-name-in-package-c.js
這個(gè)結(jié)構(gòu)可能會(huì)變得相當(dāng)長(zhǎng)。這可能僅僅是基于Unix系統(tǒng)上面的一個(gè)煩惱,在Windows上已經(jīng)有很多破解程序能夠解決文件路徑超過(guò)260個(gè)字符的問(wèn)題。
npm version 3通過(guò)展平依賴樹來(lái)解決這個(gè)問(wèn)題,因此這3個(gè)項(xiàng)目的結(jié)構(gòu)看起來(lái)會(huì)是這個(gè)樣子的:
node_modules - package-A - package-B - package-C -- some-file-name-in-package-c.js
這個(gè)變化的結(jié)果就是改變了一寫長(zhǎng)文件的文件路徑從 ./node_modules/package-A/node_modules/package-B/node-modules/some-file-name-in-package-c.js 變化為 ./node_modules/some-file-name-in-package-c.js。
你可以從這了解更多關(guān)于NPM 3依賴的解決方案。
這個(gè)方法的一個(gè)缺點(diǎn)是npm現(xiàn)在必須要遍歷所有的項(xiàng)目依賴從而決定如何展平node_modules文件夾。npm被強(qiáng)制為所有使用過(guò)的模塊建立依賴樹,這樣做的代價(jià)會(huì)很大。這也是導(dǎo)致npm install安裝速度變慢的原因之一。(請(qǐng)看文末的更新)。
因?yàn)槲覜](méi)有仔細(xì)關(guān)注過(guò)npm的變化,我猜想NPM速度變慢的原因是我每次運(yùn)行npm install的時(shí)候都需要從網(wǎng)上下載所有東西。
事實(shí)證明,我是錯(cuò)的,并且npm確實(shí)是具有本地緩存的,在其中保存了所有下載包的壓縮文件。可以通過(guò)npm cache ls命令來(lái)查看本地緩存的內(nèi)容。通過(guò)本地緩存可以加快安裝速度。
總而言之,npm是一個(gè)成熟的,穩(wěn)定的并且樂(lè)于使用的包管理器。
yarnYarn 是在2016年10月份發(fā)布的并且在Github上迅速獲取了24K+star。作為對(duì)比,npm 僅僅只有12K+ star。這個(gè)項(xiàng)目具有高資質(zhì)的開(kāi)發(fā)者比如Sebastian McKenzie (Babel.js) 以及 Yehuda Katz (Ember.js, Rust, Bundler 等等)。
從我目前收集的來(lái)看,yarn的最初的主要目的是針對(duì)npm由于之前章節(jié)提及的semver相關(guān)行為導(dǎo)致的安裝的不確定性。然而可預(yù)測(cè)的依賴樹(如果需要的話)能夠通過(guò)npm shrinkwarp來(lái)完成,這不是默認(rèn)的行為并且依賴于開(kāi)發(fā)者了解這一選項(xiàng)并且來(lái)進(jìn)行相應(yīng)的操作。
Yarn采取了一個(gè)不同的方法。每次yarn安裝都會(huì)生成一個(gè)和npm-shrinkwrap.json類似的yarn.lock文件,但是它是默認(rèn)產(chǎn)生的。除了常規(guī)信息,yarn.lock文件還包含了安裝內(nèi)容的檢查從而確保使用相同版本的包。
因?yàn)閥arn是一個(gè)才重寫的npm客戶端,開(kāi)發(fā)者能夠適宜地并行所有需要的操作并且增加一些改進(jìn),這同時(shí)也顯著提升了整體地安裝時(shí)間。我認(rèn)為速度地加快是yarn流行的主要原因。
像npm一樣,yarn也使用了本地緩存。但是不像npm,yarn在安裝已經(jīng)緩存的依賴的時(shí)候并不需要網(wǎng)絡(luò)連接,提供了一種offline模式。這個(gè)特性在npm上自從2012年就收到了請(qǐng)求,但是一直沒(méi)有得到解決。
Yarn提供一些其它的好處。比如,它允許聚合項(xiàng)目中使用的所有的licence,并且很容易看到。
有意思的一點(diǎn)事,yarn文檔對(duì)于npm態(tài)度的轉(zhuǎn)變自從其變得流行之后。
最初的yarn發(fā)布的時(shí)候說(shuō)的安裝yarn的步驟是:
最容易開(kāi)始運(yùn)行的方式是:
npm install -g yarn yarn
現(xiàn)在yarn關(guān)于安裝yarn的方式是:
注意:不建議使用npm來(lái)進(jìn)行安裝。npm是非確定性的,包是沒(méi)有簽名的,npm僅僅是做了基本的SHA1 哈希并沒(méi)有做任何整體性檢查,這對(duì)于安裝系統(tǒng)級(jí)別的應(yīng)用是有風(fēng)險(xiǎn)的。
鑒于以上原因,強(qiáng)烈建議你通過(guò)適合你操作系統(tǒng)的安裝方法來(lái)安裝yarn。
以這種速度,即使yarn宣布它們自己的registry從而讓開(kāi)發(fā)者緩慢淘汰npm我都不覺(jué)得驚訝。
同樣也是由于yarn,npm終于一是到它們需要密切關(guān)注那些強(qiáng)烈請(qǐng)求的issue。NPM最初對(duì)于yarn發(fā)布的回應(yīng)在我看來(lái)是“它是可愛(ài)的”?,F(xiàn)在,當(dāng)我重新看那個(gè)被強(qiáng)烈要求的我之前提到過(guò)的“離線”特性已經(jīng)有在被積極地解決,在我們討論這一點(diǎn)的時(shí)候。
pnpm正如我之前所提及的那樣,我只是才知道pnpm 不久通過(guò)閱讀Zoltan Kochan的“為什么我們應(yīng)該使用pnpm?”,他就是npm的作者。
我不想設(shè)計(jì)到過(guò)多的細(xì)節(jié)(因?yàn)檫@篇文章已經(jīng)很長(zhǎng)了),但是你可以從我最初的博文中可以了解一些以及推特上的討論。
但是
我想指出的是pnpm比npm以及yarn都要快。
為什么它這么快的原因?因?yàn)樗捎昧饲擅畹姆绞?,利用硬鏈接和符?hào)鏈接,以避免復(fù)制所有本地緩存的源文件,這是打敗yarn在性能上最主要的一方面。
使用鏈接并不容易,需要考慮一系列的問(wèn)題。
正如Sebastian在推特上所指出的,他最初是想在yarn里面使用符號(hào)鏈接,但最后因?yàn)楹芏嘣騺?lái)對(duì)抗yarn。
同時(shí),這個(gè)項(xiàng)目在Github上也具有2K+star,pnpm能夠讓鏈接為很多人工作。
另外,自從2017年3月它提供了所有yarn提供的優(yōu)點(diǎn),包括離線模式以及確定性安裝。
結(jié)論我認(rèn)為yarn和pnpm的開(kāi)發(fā)者都做了很好的工作。我個(gè)人的偏好是確定性的安裝,因?yàn)槲蚁矚g自己掌控并且我不喜歡驚喜。
無(wú)論最后競(jìng)爭(zhēng)的結(jié)果是什么(這也提醒了我io.js fork),我感謝yarn給npm帶來(lái)的這些麻煩因此塵埃落定之前還有很多選擇余地。
我也認(rèn)為yarn可能很早之前就考慮過(guò)硬鏈接以及軟鏈接。我想知道的是yarn團(tuán)隊(duì)針對(duì)這個(gè)想法會(huì)做些什么,取決于pnpm造成的殺傷以及用戶對(duì)于安裝速度重視的程度。
我確實(shí)認(rèn)為總的來(lái)說(shuō)yarn是一個(gè)安全的選擇,但是pnpm在某些案例上可能是一個(gè)更好的選擇。比如,對(duì)于一個(gè)需要運(yùn)行很多集成測(cè)試并且希望盡可能提高安裝依賴速度的中小型團(tuán)隊(duì)。
最后值得說(shuō)得一點(diǎn)是,我認(rèn)為npm依然提供了對(duì)于大多數(shù)用戶案例非常有用的解決方案。大多數(shù)開(kāi)發(fā)者可以繼續(xù)只使用npm客戶端。
無(wú)論是任何情況,我都感謝所有的努力保持生態(tài)健康的競(jìng)爭(zhēng)者。當(dāng)公司競(jìng)爭(zhēng)的時(shí)候,獲利的是用戶。
來(lái)自于一下@ReBeccaOrg推特的更新。
FYI, 展平不是“遍歷整棵樹”的來(lái)源。遍歷整棵樹是關(guān)于自愈。
和npm@2相比,它減緩了速度。
如果你通過(guò)rm -fr來(lái)刪除嵌套的依賴并且通過(guò)npm install來(lái)安裝,你會(huì)注意到這可能幫你解決問(wèn)題。
現(xiàn)在事實(shí)證明,npm@1-@npm@4緩存是緩慢的,非常慢。慢的超乎想象。經(jīng)常往往是比在一個(gè)快速網(wǎng)絡(luò)中下載快一點(diǎn)點(diǎn)。因此隨著npm@5的重寫(自從npm1.5就開(kāi)始計(jì)劃)它突然變得快多了。
yarn通過(guò)沙箱可以傷你免于http://registry.npmjs.org 敵對(duì)的限制,但是并不抱進(jìn)一步的保證。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/82853.html
摘要:請(qǐng)注意,在版本號(hào)之前有個(gè)字符。理論上,次版本號(hào)的變化并不會(huì)影響向后兼容性。雖然可以通過(guò)命令關(guān)閉在版本號(hào)前面使用的默認(rèn)行為,但這個(gè)只會(huì)影響頂級(jí)依賴關(guān)系。 本文作者對(duì)比了當(dāng)前主流的包管理工具npm、yarn、pnpm之間的區(qū)別,并提出了合適的使用建議,以下為譯文: NPM npm是Node.js能夠如此成功的主要原因之一。npm團(tuán)隊(duì)做了很多的工作,以確保npm保持向后兼容,并在不同的環(huán)境中...
摘要:新聞熱點(diǎn)國(guó)內(nèi)國(guó)外,前端最新動(dòng)態(tài)發(fā)布近日,正式發(fā)布新版本中提供了一系列的特性與問(wèn)題修復(fù)。而近日正式發(fā)布,其能夠幫助開(kāi)發(fā)者快速構(gòu)建應(yīng)用。 前端每周清單第 10 期:Firefox53、React VR發(fā)布、JS測(cè)試技術(shù)概述、Microsoft Edge現(xiàn)代DOM樹構(gòu)建及性能之道 為InfoQ中文站特供稿件,首發(fā)地址為這里;如需轉(zhuǎn)載,請(qǐng)與InfoQ中文站聯(lián)系。從屬于筆者的 Web 前端入門...
摘要:第一個(gè)主要的包管理器在被引用后不久就搭建起來(lái)了,并且迅速成為世界上最受歡迎的包管理器之一。簡(jiǎn)介是一款新的包管理器,在取代客戶端和其他包管理器現(xiàn)有工作流的同時(shí),又保留了對(duì)代理的兼容性。 在JavaScript社區(qū),工程師們分享了成百上千的代碼段,我們不用自己從頭編寫基礎(chǔ)組件、類庫(kù)或者框架。反過(guò)來(lái),每段代碼又或許依賴于其它的代碼段,而這些依賴就是通過(guò) package managers(包管...
摘要:淘寶鏡像切換新域名淘寶鏡像站自年正式對(duì)外服務(wù),一開(kāi)始只是想簡(jiǎn)單地做的中國(guó)鏡像站點(diǎn),回饋國(guó)內(nèi)前端社區(qū),不知不覺(jué)竟然一直運(yùn)行到現(xiàn)在。 .markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1...
閱讀 1626·2021-11-17 09:33
閱讀 1201·2021-11-12 10:36
閱讀 2481·2019-08-30 15:54
閱讀 2487·2019-08-30 13:14
閱讀 2979·2019-08-26 14:05
閱讀 3345·2019-08-26 11:32
閱讀 3074·2019-08-26 10:09
閱讀 3066·2019-08-26 10:09