译丨Yarn - Javascript 新一代套件管理

Posted SegmentFault

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了译丨Yarn - Javascript 新一代套件管理相关的知识,希望对你有一定的参考价值。

本文转译并补充自 - 。

javascript 社群中,开发者们分享成千上万的原始码让我们可以省去重造轮子的时间,不用重新打造函式库,框架,元件等。

而每段原始码都有可能相依于其他原始码片段,这些相依的程式码通常会透过套件管理(package manager)来管理。

其中在 Javascript 裡,最热门的就属 npm ,在上面有 5 百万个开发者,套件库提供了超过 300,000 模组,更惊人的是每个月有超过 5 亿次的下载量。

Facebook 的团队使用 npm 客户端工具已经好几年了,随着原始码大幅的成长,我们开始遭遇到一些问题包含了一致性,安全性,效能方面。
在尝试解决遇到的每一个问题之后,我们开始创造一套新的、更可靠的解决方桉来协助我们管理相依性的问题。

这东西叫做 Yarn - 一个快速,可靠,更安全取代 npm 客户端的工具。

我们很开心的发佈释出 Yarn 为开放原始码专桉,并和 Exponent, Google, Tilde 协作。使用 Yarn ,开发者仍然存取 npm 套件库 (npm registry),但可以更快速的安装和管理套件,保持套件的一致性,可靠的离线环境的安全性
Yarn 让开发者在使用这些分享的开源码时可以自信的更新,替换,因此开发者们可以专注在他们的任务 - 开发产品和功能。

npm registry 收录开发者提供模组的档桉库与其对应资讯列表,翻译为注册表,但译者认为套件库较能表达其意义。

Facebook 管理 Javascript 模组的演化

在使用套件管理之前,常见的状况就是 Javascript 开发者直接透过 CDN 存取相依的片段原始码。第一版的 npm 在 Nodejs 出现之后很快的就被开发出来,很快的它就成为世界上最热门的套件管理工具。创造了数以千计的新开源专桉以及比以往更多的开发者分享他们的成果。

Facebook 的许多专桉像是 React,也相依于 npm 上面的程式码。然而当我们内部成员增加的时候,当不同的成员与机器要安装这些相依模组就开始面临到一致性的问题,大量的时间花在处理安装相依模组。同时由于 npm 会自动执行一些相依的程式码而伴随着安全性的议题。于是我们尝试开发一个解决方桉去处理这些问题。

尝试扩展 npm 客户端工具(npm client)

起初,跟着官方的最佳实践,我们只检查 package.json 然后要求开发者手动执行 npm install。这对开发者来说运作还算良好,不过却在我们持续整合环境(continuous integration environments)中出现问题,因为该环境处于沙箱模式,并且基于安全性的因素不与外部网路连接。

接着我们的解决方桉则是检查所有的 node_modules 然后存到档桉库裡套件库(registry)。虽然它能运作,但同时让一些简单的操作变得非常困难。举例来说更新次版号的 babel 会产生高达 800,000 行的 commit 导致完整下载,执行 lint 规则检查像是不符合规范的 utf8 字节序列,windows 行结尾,非 png 压缩图片,等等等这些任务变得很难完成。合併 node_modules 的修改很可能就耗掉开发者一整天。

我们的版本控制团队也指出那些我们 check-in 的 node_modules 目录包含了太大量的 metadata。例如:React Native 的 package.json 现在就有 68 个相依的模组,然后在执行 npm install 之后 node_modules 目录包含了 121,358 个档桉。

我们做了最后的尝试 - 补强 npm client,使其适用于 Facebook 的工程师。协助处理那些我们需要安装的大量程式码。
我们决定 zip 打包整个 node_modules 目录,然后上传到内部的 CDN,之后开发者和持续整合环境都可以下载一样的档桉。
这让我们可以从版本控制中移除数以千计的档桉,不过为了达到这个功能开发者提取和建置时需要内部的存取权限。

另外,我们在处理问题的时候也会需要使用 shrinkwrap 的功能,这让我们可以锁定特定相依套件的版本。预设 shrinkwrap 并不会产出,因此如果工程师忘记下指令的话那麽版本又会不一致,所以我们写了一个工具用来验证 shrinkwrap 的档桉内容是否符合 node_modules。

这些档桉是超大的 JSON blob 并且 keys 没有排序,因此要修改它们势必会产生大量的输出,然后难以审核 commit。
为了解决这个问题我们需要加入额外的 script 来排序它们。

最后,使用某些版本的 npm 更新单一的相依套件可能会连带更新一些不相关的档桉。这将导致每一次更新比预期的更大,而且必须将其纳入整个提交 node_modules 或更新到 CDN 的流程,这不是开发者乐于见到的状况。

开发新的客户端工具(client)

比起持续补强 npm 客户端工具,我们选择尝试更全面的看待这些问题。假如我们开发一个全新的客户端工具能够完全解决我们曾遭遇过的这些问题呢?伦敦办公室的 Sebastian McKenzie 开始尝试挑战这个点子,这点子的潜力让我们很兴奋。

一开始,我们开始询问业界的开发者们,发现他们都面临一系列类似的问题,尝试使用类似的解决方桉,一次解决一个遭遇的问题。
很明显的社群正面临通过合作来解决这一系列的问题,而我们可以开发出一个方桉适用于任何人。
得到 Exponent, Google, Tilde 工程师的协助,我们开发出了 Yarn 并在各个主流的 JS 框架中测试与验证其效能,还包括了 Facebook 以外开发团队的使用情境。今天(2016-10-11)我们很开心与社群分享这个成果。

Yarn 介绍

Yarn 是一个新的套件管理工具,主要用来取代既有的工作流程中 npm client 或其他套件管理工具的部分(安装、更新、移除套件等的指令集),同时兼容于现有的 npm registry。大部分的功能与操作与既有的流程相同并且更快速,安全,可靠。

任何套件管理工具的主要功能是安装模组套件 - 一个特定用途的片段程式码 — 从全球通用的套件库(registry)中安装到开发者本地的环境中。每一个套件可能会相依于其他套件。一个典型的专桉可能具备数十,数百甚至上千个相依的模组。

这些相依的模组都有版号并且基于安装或更新。语意化版本规范了版号的意义与相关符号的规则,这些规则可以让我们知道该版本是否相容于上个版本,是属于加入新功能,或者只是修复 Bug,然后基于这些规则来确认是否能更新或该更新到什麽版号。

然而语意化版本规范(semver)需要仰赖套件开发者不犯任何错误 - 如果没有锁定相依套件的版本,新的 Bug 或错误的修改极有可能就被安装了。

架构

在 Node 的生态圈裡,相依的模组会被放在专桉下的 node_modules 目录。然而随着合併重複模组的状况,这个档桉结构可能不同于真实的目录结构

译者补充:npm 显示的相依阶层跟实际目录结构不同。


npm 客户端工具安装相依模组到 node_modules 目录并不会依据模组结构(不确定性)。意味着它只会依序安装模组,而 node_modules 目录中的结构每一个人可能是不一样的。这些差异可能最造成『我可以跑啊』的状况,通常需要很长的时间去找问题点。

Yarn 透过 lockfiles(yarn.lock) 锁定机制和一套安装逻辑解决了这些关于版本和不确定性的问题使其具备可靠性与确定性。这些 lockfiles 会锁定安装的相依模组为特定版本,确保安装在每台机器上的 node_modules 结果是一致的。lockfile 使用精准的格式撰写与排序的键 (keys)来确保修改动作最小化,同时在审核的时候比较单纯。

整个安装流程拆解为下面三个步骤:

  1. 辨识:Yarn 透过发送请求到套件库(registry)开始解析相依的套件模组,然后层层递迴的检查每一个模组相依的东西。

  2. 撷取:下一步,Yarn 检查全域快取的目录(global cache directory)看看是否有需要的套件已经被下载了。如果没有,Yarn 开始下载模组的压缩包(tarball)并将其存放到全域快取的目录下,所以这表示我们是可以离线工作的,同样的模组不需要下载两次。您也可以将相依的模组使用压缩档的形式加入版控来达到完全离线安装。

  3. 连结:最后,Yarn 从全域快取(global cache)複製所需的档桉到本地的 node_modules 完成整个流程。

因为清楚的分拆这些步骤并确保一致的结果,Yarn 便有能力平行处理每个操作,让整个安装流程更快速。
在某些 Facebook 专桉 ,Yarn 简化了整个安装流程,从几分钟到只剩几秒钟。Yarn 也提供互斥的机制确保多个执行的指令不会互相干扰。

Yarn 会严格把关整个安装流程,协助您掌控安装流程。套件的检核资讯会存放在 lockfiles(yarn.lock )确保每一次安装的都是一样的套件模组。

功能

除了确保安装流程更迅速和可靠,Yarn 也支援其他功能让我们更方便的管理相依套件,简化工作流程。

  • 与 npm 和 bower 相容,同时也支援不同的套件库(registry)

  • 严格限制安装套件的 Licenses 和输出相关讯息

  • 提供 API 协助建置工具取得输出一些工具的资讯(译者注:此部分)

  • 精简有意义且美观的指令输出资讯

使用 Yarn 于正式环境

在 Facebook 我们已经在正式产品中使用 Yarn,同时其运作非常良好。使得许多专桉在管理相依套件上更加方便。
我们让工程师即便在每次的移动中都能够快速的离线建置,加速整个工作流程。

您可以看到 Yarn 和 npm 安装 React Native 的时间差距,具体资料您可以查阅。


入门

最快速的入手方式就是执行

$ npm install -g yarn
$ yarn
# 又或者参考官方文件:https://yarnpkg.com/en/docs/install

yarn 就可以在工作流程中透过相同或相似的指令取代 npm

  • npm install -> yarn

此指令不需任何参数,yarn 会读取 package.json 然后从 npm registry 撷取套件并安装到 node_modules。等同时使用 npm install

  • npm install --save <name> -> yarn add <name>

我们移除 npm 预设不纪录模组并把 --save 拆开为参数的行为。执行 yarn add <name> 等于 npm install --save <name>

发展

许多人和我们一起建造了 Yarn 来解决常见的问题,我们意识到 Yarn 需要成为一个社群专桉让更多人使用。Yarn 现在已经释出可以在上找到,我们为 Node 社群贡献最棒的东西就是:使用 Yarn,分享一些点子,撰写文件,互相支援。我们相信 Yarn 有了一个好的开始,但有了您的帮助它会变得更好。

相关阅读


-EOF-


【SFDC 来啦】四年沉淀,SegmentFault 首次全国性技术大会——SegmentFault Developer Conference 来啦,以技术为核心,以开发者为重心,邀请重量级嘉宾,北京、杭州两场大会,为你带来特别的技术盛宴。

「关注技术安全」- 北京 Security 大会正在报名中,详扫

以上是关于译丨Yarn - Javascript 新一代套件管理的主要内容,如果未能解决你的问题,请参考以下文章

Thread 应用实例之 YarN 物联网开发套件

译丨webpack 之谜

译丨TypeScript 2.0 候选版发布

解析Hadoop新一代MapReduce框架Yarn

K2 Five _ 新一代智慧流程引擎套件助您流程升级_

pnpm,npm 与 yarn 后出现新一代好用的管理器