yarn
yarn
黑魔法 发表于12个月前
yarn
  • 发表于 12个月前
  • 阅读 18
  • 收藏 1
  • 点赞 0
  • 评论 0



yarn 有什么优点?
https://yarnpkg.com/

yarn 和 npm 做的是完全一样的事情:作为 nodejs 的包管理工具。既然是一样的事情,那么 yarn 必须有一些优点,才能说服大家去用。

 

根据官方网站的介绍,yarn 有以下六项特点:

 

> 离线模式(重要)

如果之前已经安装过一个软件包,再次安装时就不用再从网络下载了。

 

这一点很重要,npm 饱受诟病的一点就是,每次安装依赖,都需要从网络下载一大堆东西,而且是全部重新下载。工程多的时候比较烦人。这下子可以节约大量时间了。

 

> 依赖关系确定性(重要)

在每一台机器上针对同一个工程安装依赖时,生成的依赖关系顺序和版本是一致的。




 

之前 npm 在这里有一个处理得不好的地方。举例来说,我写的工程依赖 A, B, C 三个库,我在编写 package.json 的时候,给 A, B, C 都指定了版本号。但是 A 库可能又依赖 D, E, F 库,D 库又依赖 G, H 库。这么多关联依赖关系中,很可能某个库在指定依赖时,没有指定版本号。

 

于是,这就导致了一个问题。如果我在另一台机器上对同样的工程安装依赖,或者把这台机器工程下的 node_modules 目录删除来重新安装依赖。由于关联依赖中,没有指定版本号的库,发生了版本更新,就会导致再次安装的依赖,其中具体某些软件包的版本是不一致的

 

在这种情况下,你会发现原来能够正常运行的程序,忽然变得不能工作或一堆 BUG. 我在最近使用 react-native 编写手机应用时,就遭遇过这样的问题。只能采取一些很曲折的方式来解决。

 

yarn 采用的解决方式是,引入了一个 yarn.lock 文件来应对这个问题。lock 机制在很多包管理中都有用到。例如 ruby 的 rubygems 就会生成 Gemfile.lock.

 

yarn.lock 会记录你安装的所有大大小小的软件包的具体版本号。只要你不删除 yarn.lock 文件,再次运行 yarn install 时,会根据其中记录的版本号获取所有依赖包。你可以把 yarn.lock 提交到版本库里,这样其他同事签出代码并运行 yarn install 时,可以保证大家安装的依赖都是完全一致的。

 

这就特别适合大型项目的多人协作开发和部署。

 

> 更好的网络性能

下载软件包时,会进行更好的排序,避免“请求瀑布”,最大限度提高网络利用率。

 

> 多注册来源处理

所有的依赖包,不管他被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装,要么是 npm 要么是 bower, 防止出现混乱不一致。

 

> 网络弹性处理

安装依赖的过程中,不会因为某个单次网络请求的失败导致整个安装挂掉(这里又要黑一下 npm)。当请求失败时会进行自动重试。

 

> 扁平模式(重要)

当关联依赖中包括对某个软件包的重复引用,在实际安装时将尽量避免重复的创建。

 

为了说明这个问题,我们假设目前工程依赖 A, B, C 三个库,而他们对某个库 somelib 存在这样的依赖关系:

 

A - somelib 1.4.x
B - somelib 1.6.x
C - somelib 1.6.x

 

如果要安装 ABC 三个库,那么 somelib 会存在版本冲突。npm 会在实际安装时,给三个库分别下载各自依赖的 somelib 版本。假设 npm 先安装了 A, 由于 A 依赖 somelib 1.4.x 版本,那么 1.4.x 会变成主版本。

再安装 B, C 时,由于 B, C 依赖的都不是 1.4.x, 于是安装完之后,关系就变成这个样子了:

 

node_modules
├── A
├── somelib 1.4.x
├── B
│   └── node_modules
│       └── somelib 1.6.x
└── C
    └── node_modules
        └── somelib 1.6.x

 

明明 B, C 都依赖 1.6.x 版本,实际上 npm 却要把这个版本保存两次,这样明显是对磁盘空间的浪费。我们把这种情况就称为“不扁平的”。尽管 npm 也提供了诸如 flat 等指令去支持“扁平化”处理,yarn 明显试图在这方面做得更好。

 

总之来说,yarn 要做到的就是三点:快速,安全,可靠



实际的使用体会
 

我把自己手头的几个用到 npm 安装 js 依赖的 rails 工程还有静态 web 工程下的 node_modules 子目录删除,然后用 yarn install 重新安装依赖。

 

实际体验是速度要比 npm 快上不少,基本上可以令人满意。原来 npm install 需要 8 - 10 分钟的一个工程,改用 yarn install 后,只需 72 秒完成。

 

而且更令人欣喜的是:如果某个 js 库的某个版本在这个系统里被安装过一次,那么另一个工程再次需要安装这个库时,就完全不用再次下载。会直接从当前系统里获取这个库。大大节约了网络传输量和下载安装时间。

 

可以做一个简单的测试,对某个工程执行过 yarn install 后,删除 node_modules 目录,再次 yarn install. 会看到完全不用进行网络下载,几秒内就能再次生成 node_modules 目录。

 

这其中 lock 机制起到了很大的作用。对于经常要同时编写维护很多依赖 nodejs 的工程师而言,这是一个非常好的消息。

 

建议大家马上开始尝试使用 yarn.

 

--------------------

 

2016.10.13 补充:

 

如果觉得安装速度慢,安装源和原来 npm 是一样的,可以通用,修改方法如下:

yarn config get registry
# -> https://registry.yarnpkg.com

可以改成 taobao 的源:

yarn config set registry 'https://registry.npm.taobao.org'
# -> yarn config v0.15.0
# -> success Set "registry" to "https://registry.npm.taobao.org".
# -> Done in 0.04s.

然后 yarn install 的速度就快多了

 

另外,目前的小瑕疵还是不少,例如我刚刚遇到的问题,某个工程的 package.json 里面是这样写的:

"eslint-plugin-markdown": "*",

yarn install 的时候报错:

error Couldn't find any versions for eslint-plugin-markdown that matches *.

改成

"eslint-plugin-markdown": "latest",

之后,安装可以通过。


此外,这样的写法(直接引用本工程路径)目前也是不支持的:

"eslint-plugin-material-ui": "./packages/eslint-plugin-material-ui",

 

类似的小问题估计在近期会被各种人发现(提 issue 呗),最后如何取舍,是否都能修复,看团队的反应。目前还是可以看好。

共有 人打赏支持
粉丝 10
博文 141
码字总数 39911
×
黑魔法
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: