快速、可靠、安全的依赖管理工具
随着前端工程化体系的不断完善和"大前端"概念的丰富和发展,仅前端开发用到 Nodejs
的地方也越来越多,各大前端团队基于 Nodejs
的工具链建设也不断推动着前端开发走向新的高度;说到 Nodejs
,自然离不开其官方的包管理工具 npm
;目前,npm
已经成为世界上最大的包管理器,在其仓库中托管着超过 100
万个包,且还不包括企业内部的 npm
私服;
在 npm5
以前,npm CLI
在使用功能及体验上存在一些不尽如人意的地方,比如不太好用的版本锁定功能、安装速度慢、没有离线缓存功能等;直到 npm5
以后,借鉴 Yarn
的优势使得 npm
的使用体验得到大幅提升,比如:
package-lock.json
,锁定当前项目安装包的版本,避免同一个项目在不同地方安装会出现版本冲突的问题;--save
;不仅如此,npm
安装的速度也有大幅提升,并且增强了安全性能,一系列的优化和改进促使现在最新的 npm
更加好用和易用;
在 npm CLI
一家独大的大环境下,为什么只有 Yarn
能够异军突起呢?
Yarn
是 facebook
开源的一个快速、可靠、安全的依赖管理工具,用其官网上的话说是:它及其快速,安装速度之快前所未有!由于 Yarn
能够缓存已下载过的包,使得下次安装时无需重复下载,即便后续在无网络的环境下也能够安装成功,并且可以并行化操作,所谓“天下武功,唯快不破!”,光这一点就能够俘获大多数用户的心;加上 Yarn
会在每个安装包执行前校验其完整性,从而避免了潜在的一些安全风险;通过 lockfile
和确定性算法来安装依赖,以确保安装过的包在不同系统之间能够表现一致;可以看出来,Yarn
团队深深识意到了 npm CLI
的痛点,并且试图重新设计一个 npm
客户端:
lockfile
,避免版本冲突与系统间的不确定性;非也!
首先,不必担心 npm
与 yarn
的兼容问题,因为 Yarn
本身不具有侵入性,几乎可以无缝从 npm
切换到 Yarn
,当然,你依然可以同时使用 npm
,毕竟 Yarn
没有实现 npm
所有的命令,但是日常用到的绝大多数都可以通过 Yarn
更加高效的完成;
其次,二者都是遵循同一个 package.json
文件,即便 Yarn
会重组 node_modules
里的文件,但也是和 npm
的方式是兼容的,在项目里初次运行 yarn( install)
后,就会生成 yarn.lock
文件,只需提交该文件,团队之间即可无差别的使用相同的软件包,如果之前使用了 npm-shrinkwrap.json
或 package-lock.json
,那么锁定的版本可能依然存在冲突的可能,这时需要团队之间同时切换到 Yarn
;
再者,npm
是 Nodejs
官方的包管理工具,并且不断的改进和发展,很多实际标准还是得以 npm
为准,所以 Yarn
应该可以说是 npm
的阶段性补充,虽然到目前为止,Yarn
在某些方面依然具有优势;
一般情况下可以使用 npm i -g yarn
的方式安装,但是 npm
安装是非确定性的,程序包没有签名,并且 npm
除了做了基本的 SHA1
哈希之外不执行任何完整性检查,这给安装系统程序带来了安全风险;所以推荐使用安装系统软件的方式安装 Yarn
,比如你是 mac
用户,可以使用 brew install yarn --without-node
来安装 Yarn
,或者你是 windows
用户,可以直接下载 msi
文件来安装 Yarn
,然后配置好环境变量即可开始使用了;
Yarn
都提供了丰富而简洁的命令:
dependencies
中;yarn global
注意,这两个词整体作为一个命令前缀;package.json
文件;package.json
文件里定义的所有依赖包;package.json
中自定义 scripts
时,使用 npm
时,我们需要 npm run script
来执行,同样,Yarn
也支持该方式,同时 run
可以省略,直接 yarn script
,非常方便;process.env.CHILD_CONCURRENCY= number
,控制并行执行的子进程数以构建节点模块,可以避免在 Windows
中使用 node-gyp
时出现链接器错误;yarn link
使用系统链接的方式链接本地包,而非拷贝文件的方式,非常快;workspace
)的方式来管理项目工作区是设置你的软件包体系结构的一种新方式,它允许你可以使用这种方式安装多个软件包。
对于大型代码库,我们一般会将某些独立的功能抽离出去单独开发,并作为独立的包来发布和管理,一方面便于日常维护,另一方面也方便模块间的依赖与引用;Yarn
从 1.0
开始支持引 入工作区的方式来管理软件包;
使用 workspace
的好处:
node_modules
里,并且只生成一份 yarn.lock
,降低版本冲突的风险;如何开始使用:
package.json
,必须包含 private: true
(确保工作区不被发布出去)和 workspace
两个字段;workspace-a
和 workspace-b
两个项目目录,并使用 yarn init
初始化生成相应项目的 package.json
;Yarn
只提供工作区相关的基础功能,并且提供了其他工具使用的底层实现机制,关于工作区的高级功能使用可以关注 Lerna
;
yarn workspace
的目录结构图:
当你安装某个包时,Yarn
会将其缓存下来,下次再安装这个包时无需重复下载;
--offline
从本地缓存中安装某个包,没有可用的则会报错;--prefer-offline
优先从本地缓存安装某个包,没有可用的则从重新下载最新的;yarn cache [ls|list|clean|dir] [flags]
通过 yarn cache
我们可以进行设置缓存目录、清除缓存、查看已缓存的包等操作;yarn config set yarn-offline-mirror ./npm-packages-offline-cache
通过该命令我们可以设置离线镜像的目录, 为了保持该目录的及时更新,我们还需要设置一下,yarn config set yarn-offline-mirror-pruning true
,以后安装某个包时便会将该包的 .tar.gz
压缩包下载到该目录,供离线安装时使用;warning Plug'n'Play on Windows doesn't support the cache and project to be kept on separate drives
Plug'n'Play
简称 pnp
,是为了提供一种更加高效的模块查找机制,消除了项目中的 node_modules
目录,取而代之的是 .pnp
目录和 .pnp.js
,在该模式下,yarn
会将所有的包缓存到一个目录里面,通过 .pnp.js
告诉 node
在没有 node_modules
的情况下如何去查找模块;我们试想一下,咱们的项目里以后不会出现 node_modules
了,并且所有的依赖包都在一个公共的目录里面,即便同一个包的多个版本也能安然无事的并存,那么当我们安装项目时,速度将大大提升;同时通过 .pnp.js
告诉 node
依赖包的具体位置,那么引用查询模块的效率也将大大提升,并且少了很多可能的文件查找过程;
目前还是实验性特性,并且还不支持 windows
,从 1.12 以后的版本开始,我们可以使用 --pnp
或 --enable-pnp
来体验该特性;
由于该机制改变了原来 node
查找依赖模块的方式,所以一些开源项目在未适配该机制时可能会出先找不到模块的错误,可以在 npm
上查询 pnp
找相应的适配包来解决;
以上,我们对 Yarn
的使用体验及速度优势有了初步了解,在实际工作中,我们可以根据实际情况灵活的选择使用 npm
命令还是 yarn
命令;在我看来,至少目前来说,Yarn
在实际使用的某些方面是依然具有优势的,所以,还等什么呢?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.