章节索引 :

Yarn 的 workspace 和离线安装策略

前言:大家好,很高兴和大家又见面啦!在之前得几个小节里,主要给大家介绍了关于 Yarn 得基础知识,大家只要在平时得开发过程中,多多得尝试使用,一定能很快得掌握。那本章开始,我将给大家讲解一些关于 Yarn 得高级特性,有助于帮助大家理解,为什么 Yarn 这个依赖管理工具,在短时间就能广泛的在前端架构中被大家热衷使用,并且发展成为足以媲美 npm 的主流管理工具。

1. 关于 Yarn 的 workspace

1.1 为什么要使用 workspace

在前面的章节中,给大家简单提过这样一个观点,就是 yarn 的官方文档教程中表示,Yarn 并不希望开发者像使用 npm 那样,在不考虑内存等相关因素的情况下,可以随心所欲的全局安装依赖然后去使用它。它更希望我们针对于每一个项目,单独去维护我们的项目相关依赖。

基于这种使用思路,那么我们现在思考一个问题:单独维护每个项目,这样可以根据项目的 package.json 去维护每个项目的依赖,非常的清晰、方便。但是同时也暴露出了一些如重复安装,占用存储空间等缺点。所以,为了解决这些不足,Yarn 的 workspace 策略应运而生。

1.2 workspace 能帮我们解决什么问题?

  • 依赖关系可以链接在一起,这意味着你的工作区可以相互依赖,同时始终使用最新的可用代码。这也是一个相对于 yarn link 更好的机制,因为它只影响你的工作空间树,而不是整个系统
  • 能帮助你更好地管理多个子项目的依赖库,这样你可以在每个子项目里使用独立的 package.json 管理你的依赖,又不用分别进到每一个子项目里去 yarn install/upfrade 安装/升级依赖,而是使用一条yarn命令去处理所有依赖。就像只有一个package.json一样。
  • yarn会根据就依赖关系帮助你分析所有子项目的共用依赖,保证所有的项目公用的依赖只会被下载和安装一次。

这样就能完美的解决了我们上文所分析的问题。那么接下来,我就带领大家通过实际例子的方式,具体的使用一下 Yarnworkspace 吧!

1.3 如何使用 workspace

当我们需要构建一个大型的前端项目,里面包含几个并列的子项目时,我们就可以使用yarn得 workspace 。目前国内得许多经典开源项目,如 vue、react 等,都是用得这一思路去构建他们得项目。

1.3.1 没有使用workspace时,我们怎么做的

在不使用 workspace 时,我们的项目目录通常是这样的

projects/
| project1/
|  |--package.json
|  |--node_modules/
|  |  |--vue/
|--project2
|  |--package.json
|  |--node_modules/
|  |  |--vue/
|  |  |--project1/

其中第一个子项目 project1 的 package.json 配置可以简化为:

{
  "name": "project1",
  "version": "1.0.0",
  "dependencies": {
    "vue": "1.0.0"
  }
}

第二个子项目 project2 的 package.json 配置可以简化为:

{
  "name": "project2",
  "version": "1.0.0",
  "dependencies": {
    "vue": "1.0.0",
    "project1": "1.0.0"
  }
}

这种经典的传统使用方法,就会暴露出如上文所说的问题,总结本案例的不足点如下:

  1. 两个子项目有相同的依赖 vue ,每个子项目都会下载一次 vue 依赖,不仅浪费开发效率,还占用额外空间,当子项目较多时,问题更加明显。
  2. 第二个子项目 project2 依赖于第一个子项目 project2 ,而 project1 如果没有发布到 npm 仓库,那就得使用yarn link命令来配置依赖,非常不方便。
  3. 需要使用 yarn build 构建项目时,需要每个子项目分别构建,不能统一构建。

1.3.2 使用workspace示例

使用 workspace 不用安装别的依赖,直接新建一个项目根目录 projects, 初始化项目即可。然后修改初始化的 package.json 文件为:

{
  "private": true,
  "workspaces": ["project1", "project2"] // 也可以使用通配符设置为 ["project*"],开源社区则都基本上使用 "workspaces": ["packages/*"] 的目录结构。
}

两个子项目 project1 和 project2 如上文配置不变。

在根目录 projects 目录下执行 yarn install

$ yarn install
yarn install v1.22.0
info No lockfile found.
[1/4] ?  Resolving packages...
[2/4] ?  Fetching packages...
[3/4] ?  Linking dependencies...
[4/4] ?  Building fresh packages...
success Saved lockfile.
✨  Done in 0.56s.

此时查看目录结构如下:

projects/
|--package.json
|--project1/
|  |--package.json
|--project2
|  |--package.json
|--node_modules/
|  |--vue/
|  |--project1/ -> ./project1/

备注

  • 如果需要某个特殊的 子项目 不受 Yarn Workspace 管理,只需在此 workspace 目录下添加 .yarnrc 文件,并添加如下内容禁用即可
workspaces-experimental false
  • 如果想单独添加或者移除某个子项目的依赖,可以使用如下命令:
$ yarn workspace project1 add vue --dev
$ yarn workspace project1 remove vue 

以上便是 yarn 的 workspace 简单用法。

2. 浅谈Yarn的离线安装策略

我们知道,yarn 这个依赖管理工具和其他的管理工具对比,一大特点就是快。根据以往经验来看,当我们使用 npm ,因为网速或者其他的,如需科学上网才能下载依赖等问题时,使用 yarn 代替 npm 去下载时,往往会有很好的效果。

那么,如果是更加极端的情况,比如我们当前没有网络的情况,想下载相关依赖,可以吗?答案是可以,只要我们之前在有网络时候在本地下载过这个依赖,那就可以按照如下方法去离线下载相关依赖。

  1. 设置离线存储目录,使用下面命令会在当前项目路径生成一个 yarn-offline 文件夹用来存放构建的.tgz离线文件。
yarn config set yarn-offline-mirror ./yarn-offline
  1. 离线文件夹不会同步你的包,可能会导致一些的问题,所以需要清除用不到的压缩包。
yarn config set yarn-offline-mirror-pruning true
  1. 删除 node_modules 文件夹下面的 yarn.lock,生成离线文件。
yarn install
  1. 模拟没有网络的环境,删除上面安装的 node_modules 文件,并执行下面命令。
yarn --offline

以上便是使用 yarn 进行离线安装依赖的方法。

3. 小结

Yarn 作为后起之秀,发展成现在深受广大开发者喜爱的依赖管理工具,有很多 npm 等管理工具所不具备的特性和优势,本文就给大家讲解了 yarn 的两个高级用法:workspace 和离线缓存策略。希望大家在熟练掌握它的基础用法的同时,也能深入理解 yarn 的高级用法与特性。