yarn
Yarn 是一个快速、可靠、安全的依赖管理工具。
它的官方描述如下
Yarn is an established open-source package manager used to manage dependencies in JavaScript projects. It assists with the process of installing, updating, configuring, and removing packages dependencies, eventually helping you reach your objectives faster with fewer distractions.
Yarn 是一个成熟的开源包管理器,用于管理JavaScript项目中的依赖关系。它有助于安装、更新、配置和删除包依赖,最终帮助您更快地实现目标,减少干扰。
1. 导入 package-lock.json 文件
如果你的项目之前使用的是npm和管理依赖,可以在项目根目录下执行下面的命令把项目从npm的lock文件转换为yarn。这样就不会丢失项目依赖的版本信息。
yarn # 安装依赖
yarn import # 导入package-lock.json文件中的版本信息
直接在项目根目录下运行 yarn
也可以把 npm 项目转换为 yarn 项目。但它会从 package.json 的 dependencies 字段中读取依赖,而不是从 package-lock.json 中读取,这样可能会导致依赖的版本不一致,从而造成项目无法运行。而 yarn import
会从 package-lock.json 中读取依赖的版本信息,这样就不会出现依赖版本不一致的问题。
2. Plug'n'Play
2.1 什么是PnP?
Plug'n'Play (PnP) 是 Yarn 的一种新特性,它是一种新的依赖解析机制,可以让你在不需要 node_modules 文件夹的情况下运行项目。这样可以减少磁盘空间的占用,加快项目的启动速度。
2.2 为什么会有PnP
传统的yarn依赖安装步骤大概是这样的
- 解析 package.json 文件中的依赖项版本号
- 下载对应版本的 tar 包保存到本地镜像
- 把tar包解压到本地缓存
- 把缓存复制到 node_modules 文件夹
而在运行时也会有类似的步骤
- 解析 require 语句
- 从 node_modules 文件夹中找到对应的模块
- 如果没有找到,就会向上级目录查找,直到找到为止
- 如果找到了,就会加载模块
这样的方式会导致两个问题
- 依赖安装的速度慢
- 项目启动的速度慢
PnP 就是为了解决这两个问题而生的。
2.3 如何使用PnP
要使用PnP首先确保你的项目是使用yarn管理的,然后在项目根目录下执行下面的命令,yarn就会使用pnp模式来管理依赖。
yarn --enable-pnp
# --enable-pnp 的简写
yarn --pnp
还可以在 package.json 中添加installConfig
字段来启用pnp,添加以后在使用yarn安装依赖时使用使用的yarn版本支持pnp就会自动使用pnp模式。
{
"installConfig": {
"pnp": true
}
}
使用PnP模式安装依赖不会生成 node_modules 文件夹,而是生成一个.pnp
目录和一个.pnp.js
文件,这两个文件是pnp的核心文件,.pnp
目录保存解压以后的依赖文件,.pnp.js
文件保存了依赖的解析规则。使用 yarn start
或 yarn run
时会自动加载 .pnp.js
文件,然后根据规则解析依赖。
2.4 PnP的优势
使用PnP的好处显而易见,它取消了所有的依赖层级,直接根据 .pnp.js
中的规则加载依赖,这样就可以减少大量的IO操作,从而加快项目的启动/编译速度。
2.5 PnP的劣势
PnP的劣势也很明显,它会导致一些依赖的插件无法正常工作,比如babel-plugin-module-resolver
,因为它会根据 node_modules 的层级来解析依赖,而PnP取消了这种层级,所以这种插件就无法正常工作。
它还会导致IDE的代码提示无法正常工作,因为IDE会根据 node_modules 的层级来解析依赖,而PnP取消了这种层级,IDE也就无法正常解析依赖。
不光是某些插件和IDE,因为Node的生态就是有node_modules的,所有大部分的插件和工具都是基于node_modules的,PnP大胆的取消了node_modules,这样就会导致PnP和Node原生态的割裂,这也是PnP无法普及的原因之一。