Published on

NPM共享依赖

Authors

关于共享依赖(也叫跨项目依赖)是在 monorepo 中常见的场景,它被用来处理公用依赖的问题。

monorepo 中,多个项目共享相同的依赖是非常常见的。处理这种场景时,开发人员需要考虑如何管理和维护这些共享依赖,以确保它们能够被各个项目正确地使用。

一些常见的方法包括:

  1. 使用工作区(workspaces):像 yarn 或者 npm v7+ 这样的工具可以通过工作区功能来管理 monorepo 中的共享依赖。这样可以确保所有项目共享同一份依赖,并且可以更轻松地进行版本管理和依赖升级。
  2. 符号链接:将共享的依赖链接到每个子项目中,确保它们能被正确引用和使用。
  3. 私有包管理:有些开发团队会选择使用私有的包管理器,比如 Vedaccio 或者 Sinopia,来管理自己的共享依赖。

这次记录共享依赖,并没有涉及到 monorepo 的场景,而是在学习过程中,有很多的 React demo 要进行展示,这些又没有放在同一个项目中,而是分章节来进行展示的,所以才有了共享依赖的需求。

在上述三个方法中,我选择了使用工作区的方式来共享依赖,原因如下:

  1. 简化了依赖管理,所有项目共享同一份依赖
  2. 可以更轻松地进行版本管理和依赖升级
  3. 不需要和符号链接一样,需要手动进行设置(尤其在子项目过多的情况下,简直是噩梦)
  4. 也不要和私有包管理一样,需要额外的配置和维护。并且对于私有包管理器来说,还有一定的学习成本和团队来进行支持

那么 workspaces 如何设置呢?

比如我们现在有一个根目录 A,然后在下面有两个子项目 B 和 C。这个时候我们可以将 A 目录视为一个 monorepo(单体仓库),并在根目录的 package.json 文件中配置工作区,然后让子项目 B 和 C 成为这个工作区的一部分。通过这种方式,所有的子项目将共享同一个 node_modules 文件夹。

  1. 在根目录下使用 npm init -y 或者 yarn init -y 生成一个 package.json 文件
  2. package.json 文件中,添加工作区配置
{
  "name": "root",
  "private": true,
  "workspaces": [
    "B/b_demo",
    "C/c_demo"
  ]
}

如上,在 workspaces 属性下的 B 和 C 就是子项目的目录名 + 项目名(也就是 package.json 中的 name 字段)。

3.进入子项目 B 和 C 的目录,在它们各自的 package.json 文件中,移除掉所有的依赖项。(注意哦,只是删除依赖项的属性,其他部分不要动

4.回到根目录 A,运行以下命令安装所有依赖项:npm install 或者 yarn,后面如果有其他的子项目加进来,我们还要做到:

a. 确保每个子项目都是通过 npm 或者 yarn 初始化出来的,不然根目录下的 workspaces 中找不到对应的子项目

b. 如上,根目录中 package.json 中的 workspaces 里,一定要是正确的路径 + 项目名

这样设置好之后,我们的 B 和 C 都会共享同一个 node_modules 文件夹。

5.那在之后如果我们有需要安装一些依赖到共享依赖中,在使用 npm 或者 yarn 进行安装时,需要加上 -W 的参数,比如 npm install react -W,这样才能让这个共享依赖被整个工作区使用。