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