为什么向根工作区package.json添加依赖时,Yarn会发出警告?

46
每当我向工作区项目的根目录添加依赖项时,例如:yarn add assets-webpack-plugin -D,我会收到以下错误提示:

运行此命令将向工作区根目录添加该依赖项,而不是工作区本身,这可能不是您想要的 - 如果您确实需要,请使用 -W标志(或 --ignore-workspace-root-check)再次运行此命令以明确表示。

另一种方法是将其添加到每个需要它的项目中,然后您将面临每个项目具有不同依赖项和锁定文件的问题。
3个回答

50

由于您正在使用Yarn Workspaces并且它管理所有项目(工作区)的依赖项,因此您应该将每个项目的依赖项添加到其自己的package.json中,而不是工作区根目录。 Yarn只使用放置在工作区根目录中的一个yarn.lock文件,并尽可能地将所有项目的依赖项移动到工作区根目录的node_modules中以防止重复。尽管某些依赖项需要放置在其自己项目的node_modules中;例如当工作区根目录具有对awesome-package@2.1.1devDependency时,而项目具有对同一包的另一个版本(例如1.2.5)的依赖关系,它们彼此不兼容。假设您的工作区目录结构如下:

├── workspace-root
|   ├── package.json
|   ├── workspace-a
|   |   ├── package.json
|   ├── workspace-b
|   |   ├── package.json

运行yarn命令后,无论是在工作区根目录还是任何工作区子目录中,您将拥有以下目录结构:

├── workspace-root
|   ├── node_modules
|   ├── package.json
|   ├── yarn.lock
|   ├── workspace-a
|   |   ├── package.json
|   |   ├── node_modules
|   ├── workspace-b
|   |   ├── package.json
|   |   ├── node_modules

只有在你想要从工作区根目录运行脚本并且它需要依赖项时,才向工作区根目录添加依赖项。在这种情况下,项目独立于该依赖项,因此您可以忽略该警告。

yarn 为什么会警告?

如果将项目的常见依赖项添加到工作区根目录,则不会出现在项目的 package.json 中。因此,如果分离一个项目,则其自己的 package.json 中不会拥有所有依赖项,因此运行分离的项目的 yarn install 将导致其自己的 node_modules 中没有所有的依赖项。显然,分离的项目无法工作,您需要解决缺失依赖项的问题以解决该问题。

更多关于 Yarn Workspaces 的信息

Yarn Workspaces 是一项功能,旨在更轻松地管理彼此相关的项目的依赖项。例如,当您的项目具有相似的依赖关系时,可以将每个项目声明为工作区。它可以避免很多重复。另一个重要的用例是单库存储库(monorepos)

  

尝试将项目拆分为多个包的人都知道一次跨多个包进行更改有多么困难。   为了使此过程更轻松,一些大型项目采用了单库存储库   方法或多包存储库,可以减轻在多个包中编写代码的负担。

     

每天由 JavaScript 开发人员使用的几个项目都是作为单库存储库进行管理的:Babel、React、Jest、Vue、Angular。

使用 Yarn Workspaces 会带来以下好处:

  
      
  • 它允许您设置多个包,这样您只需要运行一次 yarn install 就可以一次性安装所有包。
  •   
  • 您的依赖项可以链接在一起,这意味着您的工作区可以相互依赖并始终使用最新的可用代码。

  •   
  • 这也比 yarn link 更好,因为它只影响您的工作区树而不是整个系统。

  •   
  • 所有项目依赖项将一起安装,使 Yarn 更具优化它们的灵活性。

  •   
  • Yarn 将使用单个锁文件而不是每个项目都有不同的锁文件,这意味着冲突更少,审核更容易。

  •   

7
您的回答涉及工作区的预期用途,但没有实际解释错误原因。我也遇到了同样的问题,而且在这个项目中(或者其他我能想到的地方)从来没有使用过yarn工作区。为了不出现这个错误信息,我现在必须采用工作区吗?我需要在package.json中添加/更改些什么吗? - rainabba
@rainabba,我已经准确地解释了错误消息的原因。在问题中,已经解释了如何避免错误消息:通过再次运行此命令并使用-W标志(或--ignore-workspace-root-check) - Abdollah
2
我相信在这个问题中有一些假设,但我认为我缺乏发现它们的知识。我会开始我的问题,但我预计它会被标记为重复,因为它是完全相同的问题。一个重要的事实是,我不使用工作区(无论如何都不知道)也不构建“monorepos”。因此,我甚至不确定“根工作区package.json”具体是什么。我知道我的项目package.json是什么(就像我曾经使用过的所有其他项目一样),但突然间yarn给我这个警告并让我使用-W。问题是,“为什么”? - rainabba
1
工作区根目录就是项目目录的父级目录。希望示例目录层次结构能够说明问题。 - Abdollah
@rainabba,一旦您的根package.json具有“工作区”选项,您就可以为项目“启用”工作区,因此该警告已启用。 - bombillazo
显示剩余2条评论

6
如果你在 package.json 中声明了"工作区",那么你已经选择了工作区并且设置必须正确。这似乎只有在使用单一仓库时才有意义。对于这个问题,单一仓库是一个具有“根”package.json的大型仓库,其中声明了工作区以及开发依赖项。里面将会有其他“包”(具有自己的package.json但不是自己的仓库的项目)。
当你想要添加包到这些"工作区"(参见 https://yarnpkg.com/lang/en/docs/workspaces/ ) 或者 "packages",并且你是从根目录工作时,你必须使用 Yarn 命令指定你要操作的工作区。
如果它是根目录的开发依赖项,那么这不是问题。因为假定你的"根"项目不会有它自己的"生产"依赖项,并且它们只会存在于工作区。如果它不是开发依赖项,并且你没有指定工作区(https://yarnpkg.com/en/docs/cli/workspace),那么你将会看到警告和如何覆盖的方法。

9
我很迷茫。你如何为工作区安装依赖项?进入工作区并运行 yarn add somepackage 会创建一个新的 lockfile。运行 yarn workspace workspace-package-name add somepackage 也会在该工作区中创建一个新的 lockfile。 - tamj0rd2

0

简单回答

您可能没有正确地索引到应用程序的目录。

例如,您可能有一个像这样结构化的next.js应用程序:

myApp
- /app
- /functions

如果您在IDE终端中的myApp目录中尝试删除软件包,Yarn将会抛出此警告。因此,解决方案可能就是这么简单:

cd /app
yarn remove somePackage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接