请选择 进入手机版 | 继续访问电脑版
  • 关注官方微信 微信公众号 添加方式:
    1:搜索微信号(gogolinux
    2:扫描左侧二维码
  • 登录 注册
  • 一起学LINUX - GOGOLINUX

    查看: 580|回复: 0

    如何评价Facebook推出的JavaScript模块管理器yarn?

    [复制链接]

    6

    主题

    6

    帖子

    6

    积分

    新手上路

    Rank: 1

    积分
    6
    发表于 2019-6-5 14:20:11 | 显示全部楼层 |阅读模式
    问题描述如下:

    facebook在其开发者博客上,http://code.facebook.com/posts/1840075619545360上 公布了他们开发的新一代包管理工具yarn,项目地址:Yarn。
    小玩了下,感觉和Rust的包管理工具Cargo很像。
    我们知道npm有很多缺陷,那么重新设计这个yarn解决了哪些问题呢?解决的怎么样?

    参考答案如下:

    就在昨天(2016 年 10 月 11 日),facebook 公开了新的 javascript 包管理工具 yarn, 用来替代目前被广泛使用的 npm (nodejs 自带的包管理工具)​


    github 项目地址:
    GitHub - yarnpkg/yarn:    Fast, reliable, and secure dependency management for JavaScript.

    仅仅一天的时间,github 上的这个项目已经得到了 200+ 的 watch 以及 8000+ 的 star. (还在急速增加中……人们到底是有多讨厌 npm)




    yarn 有什么优点?

    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.xB - somelib 1.6.xC - 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 要做到的就是三点:快速,安全,可靠
    LOGO 是猫咪(这也算优点?)




    实际的使用体会

    我把自己手头的几个用到 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.


    参考答案如下:

    刚才粗看了下文档。

    其实npm client的最大问题地球人都知道,就是慢。以这点来说,yarn其实并不是最快的……


    以下是拿我们某个大项目的测试:

    cnpm在无缓存下全新安装:
    real        0m53.079s
    user        0m41.432s
    sys        0m19.383s

    无更新重新安装:
    real        0m11.099s
    user        0m2.907s
    sys        0m1.385s

    再次全新安装:
    real        0m44.707s
    user        0m35.417s
    sys        0m16.281s

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

    yarn在无缓存下全新安装(公平起见,我把registry换成了淘宝的镜像):
    real        1m49.653s
    user        1m30.335s
    sys        0m48.305s

    无更新重新安装:
    real        0m0.915s
    user        0m0.672s
    sys        0m0.141s

    再次全新安装:
    real        1m4.497s
    user        0m52.680s
    sys        0m33.219s

    删除lock文件后重新安装(像切换branch可能发生lock改变):
    real        0m34.586s
    user        0m28.289s
    sys        0m6.394s


    以上测试中cnpm比yarn快很多。只有在有lock文件时,yarn直接就结束了。而cnpm没有lock(也不支持shrinkwrap),因此无法享受这样的秒完,不过即使在这样不利的情况下(意味着cnpm要重新解析一遍所有依赖),在我们这个有超过1000个依赖,总量达392M的node_modules下,也只花了10秒。


    就速度这点来说,cnpm完胜,然而阿里的同学们的宣传完败给facebook……



    下面讲一下yarn和npm和cnpm不同的地方:

    1. yarn使用了和npm3一样的模块布局,不像cnpm是用link的方式。cnpm的方式能在安装依赖时获得更快的速度(因为只需要做link),代价是比较难实现shrinkwrap(但是并不是不能实现类似yarn的lock)。

    2. yarn实现了lock。lock看上去比npm的shrinkwrap要更简单一点,但是作用是类似的。cnpm没有类似的功能。yarn的一个重要改变是,它默认会生成lock,而npm是默认不生成。这是一个巨大的策略改变。像facebook这样的公司默认使用lock并手动管理依赖版本升级是非常正常的,但是对于一般开源项目是否默认使用lock是好的策略?这改变了npm生态的默认习惯,后果暂时无法评估。

    3. yarn改变了一些npm命令的名称,比如 yarn add/remove,感觉上比 npm 原本的 install/uninstall 要更清晰。不过这只是很小的改进,且yarn也没有提供如 npm i 这样的缩写,所以我个人觉得其实也没多好。
    yarn还提供了version命令,交互式的依赖版本升级工具。还没有很多经验,难以确定这个工具到底是不是比ncu好。
    yarn还使用了deterministic的算法确保无论安装顺序如何,结果一致。而npm3下包的最终布局与安装顺序有关。facebook的人说这可能造成“works on my machine”的bug,不过我个人从来没有遇到过也没有听说过这样的bug。且npm3的不一致只出现在中途加减包的情况,一次干净的安装其实总是得到一样的结果的。所以至少就我所知,我也没觉得这是一个问题。



    结论:从目前看到的情况,在已经有 cnpm 的情况下,我认为 yarn 提供的额外价值并不特别高。当然,国外社区的大部分人并不知道 cnpm 的存在,对于这些同志 yarn 就是救星了(然而实际上还有pnpm/ied等其他第三方npm client)。讲真,阿里同志的宣传要加强啊!最好能联合国内其他公司一起宣传宣传。否则 facebook 吹个牛就马上蹭蹭蹭长星,真是没意义。当然,我觉得lock功能还是有用的,建议 @死马 、 @苏千 赶紧加上。当然,指望 cnpm 能跟 yarn 一样流行,不太现实。毕竟大部分人(特别是react党)是 facebook 的脑残粉。我建议你们最好马上 fork 一个 cyarn (内部就用 cnpm,但是命令兼容 yarn 就好),这是釜底抽薪的办法。

    BTW,我个人其实希望facebook的人把精力花在babel上才是正道。


    以上。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    分享到:
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    官方微博:

    官方头条号:

    官方微信

    手机访问:

    官方微信

    QQArchiver 手机版 小黑屋 一起学LINUX - GOGOLINUX 闽ICP备18025837号-1 Discuz! X3.4 Powered by © 2001-2013 Comsenz Inc. 

    本站资源均来自互联网或会员发布,如果侵犯了您的权益请与我们联系,我们将在24小时内删除!谢谢!

    快速回复 快速发帖 返回顶部 返回列表