[译] npm, yarn以及pnpm的不同之处

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的。

过去的一周,我一向花时候浏览npmyarn以及pnpm相干的东西,想总结一下然后分享我的发明。我的目标读者是历久的npm用户,而且不愿意消费太多的时候相识有若干种npm的替代品,比方我本身。我只会关注这三种最常说起的(关于我)而且不会包括:iednpm-install以及npmd,因为关于它们我是一窍不通。

另有重要的一点需要指出,直到写这篇文章的时刻,还没有一个具有合作力的库的目标是替代NPM的registry(就是存储包的处所),它们的目标都是替代npm敕令行客户端,供应别的一个可用的用户界面以及行动,而且其功用也是相似的。

NPM

npm自从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 installnpm会装置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是一个成熟的,稳固的而且乐于运用的包治理器。

yarn

Yarn 是在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也运用了当地缓存。然则不像npmyarn在装置已缓存的依靠的时刻并不需要收集连接,供应了一种offline形式。这个特征在npm上自从2012年就收到了要求,然则一向没有得到处理。

Yarn供应一些别的的长处。比方,它许可聚合项目中运用的一切的licence,而且很轻易看到。

有意思的一点事,yarn文档关于npm立场的改变自从其变得盛行以后。

最初的yarn宣告的时刻说的装置yarn的步骤是:

最轻易最先运转的体式格局是:

npm install -g yarn
yarn

如今yarn关于装置yarn的体式格局是

注重:不发起运用npm来举行装置。npm黑白确定性的,包是没有署名的,npm仅仅是做了基础的SHA1 哈希并没有做任何团体性搜检,这关于装置体系级别的应用是有风险的。

鉴于以上缘由,猛烈发起你经由过程合适你操纵体系的装置要领来装置yarn。

以这类速率,纵然yarn宣告它们本身的registry从而让开发者迟缓镌汰npm我都不以为惊奇。

一样也是因为yarnnpm终究一是到它们需要亲昵关注那些猛烈要求的issue。NPM最初关于yarn宣告的回应在我看来是“它是可爱的”。如今,当我从新看谁人被猛烈要求的我之前提到过的“离线”特征已有在被积极地处理,在我们议论这一点的时刻

pnpm

正如我之前所说起的那样,我只是才晓得pnpm 不久经由过程浏览Zoltan Kochan的“为何我们应当运用pnpm?”,他就是npm的作者。

我不想设想到过量的细节(因为这篇文章已很长了),然则你可以从我最初的博文中可以相识一些以及推特上的议论

然则

我想指出的是pnpmnpm以及yarn都要快

为何它这么快的缘由?因为它采用了奇妙的体式格局,应用硬链接和标记链接,以避免复制一切当地缓存的源文件,这是打败yarn在性能上最重要的一方面。

运用链接并不轻易,需要斟酌一系列的题目。

正如Sebastian在推特上所指出的,他最初是想在yarn内里运用标记链接,但末了因为许多缘由来匹敌yarn。

同时,这个项目在Github上也具有2K+star,pnpm可以让链接为许多人事情。

别的,自从2017年3月它供应了一切yarn供应的长处,包括离线形式以及确定性装置。

结论

我以为yarnpnpm的开发者都做了很好的事情。我个人的偏好是确定性的装置,因为我喜好本身掌控而且我不喜好欣喜。

不管末了合作的效果是什么(这也提醒了我io.js fork),我谢谢yarnnpm带来的这些贫苦因而尘埃落定之前另有许多挑选余地。

我也以为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 仇视的限定,然则并不抱进一步的保证。

    原文作者:neal
    原文地址: https://segmentfault.com/a/1190000009302074
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞