随着NPM工作区的出现,Lerna还有必要继续使用吗?

50
Lerna在NPM 7.0.0工作区还需要吗?
我对这个新的npm功能没有太多经验。 npm/RFCs写道:
首先,有一个解决问题的替代方案,就是使用非常流行的项目Lerna提供的一些功能。
另外,还有一个选择是仅支持安装(或者像Lerna称之为bootstrap)这个提案的方面,采用一个功能较少但仍然能实现基本目标的方法,即改善管理多个子包的用户体验。但根据在研究阶段收集到的所有反馈,这个选择对于参与其中的维护者社区来说远不如第一个选择受欢迎。
非常期待每一个答案和解释 :)
3个回答

50

NPM自版本7开始支持工作区,已经有两个主要版本了。

通过工作区,npm i / npm ci会处理嵌套包和符号链接。可以在单个或所有工作区上运行npm runnpm exec

npm run test --workspace=a --workspace="name-from-package-dot-json"

npm run test --workspaces --if-present

话虽如此,lernanpmyarn工作区提供了更多高级功能。

一个很好的例子是命令:lerna changed,它会给出自上次标记发布以来发生变化的软件包列表,这对于CI/CD非常有帮助。欢迎您探索lerna提供的额外命令。

我写了一篇文章,深入介绍了配置,如果您想使用npm7进行单体库开发,那么不使用lerna绝对是一个选择,但您可能需要在CI/CD方面做更多工作,并自己添加一些开发脚本,这将影响嵌套的软件包。另外,在我看来,lerna更适合开发库而不是应用程序。


2
从npm 7.7开始,npm runnpm exec现在得到支持,并可用于在多个工作区/包之间运行命令。 - trusktr
我已经更新了这个答案,包括了当前的npm功能。希望这样可以满足你的要求,@jony89。 - mikemaccana

16
答案是肯定的,您仍然需要Lerna或其他工具来补充npm@7工作区所提供的功能。以下是npm@7工作区(截至本回答撰写时)无法处理的内容:
了解单体库拓扑结构
npm工作区在一定程度上了解单体库包的拓扑结构。例如,工作区知道package-c使用package-a和package-b作为其依赖项。但需要注意的是:
$ npm run build --workspaces

这个命令将会对所有的monorepo包运行npm run build

假设package-a依赖于package-b,而package-c同时依赖于package-a和package-b。执行该命令时,执行顺序取决于你在package.json中的workspaces数组。如果你有以下配置:

{
  "workspaces": ["package-a", "package-b", "package-c"]
}

那么构建顺序应该是:

  • package-a
  • package-b
  • package-c

但正确的顺序应该是:

  • package-b
  • package-a
  • package-c

为了让构建按照正确的顺序进行,你应该确保在 package.json 文件中按照正确的顺序列出它们:

{
  "workspaces": ["package-b", "package-a", "package-c"]
}

变更管理

Lerna可以检测monorepo中的变更并提供您已更改的软件包列表。如果您只想运行更改后的软件包测试,这非常方便。截至2021年10月5日,npm@7工作区尚不能做到这一点。

发布

Lerna可以管理您的软件包版本和发布。它提供了两种不同的版本管理策略:固定版本和独立版本。它生成变更日志,并仅将更改的软件包发布到npm。

当然,还有很多其他功能,但这些是您仍然需要在npm@7工作区之上使用Lerna的主要内容。如果您使用Lerna或其他工具,那就由您决定。

我在一篇文章中记录了我在使用Lerna维护JavaScript monorepo时学到的所有things。它描述了在npm@7引入后,monorepo管理流程如何显着简化,但为什么我们仍然需要在其之上使用Lerna或其他工具。


3
另外,“常规提交”(conventionalCommits)已经预先设置在“lerna”中,可以完全自动化生成变更日志。此外,要获得更细粒度的控制,您可以仅执行版本控制,并使用调用npm publish ||:的简单脚本进行发布(如果没有要发布的内容,则不会以零代码退出;而npm不会让您发布未经修改的package.json文件)。 - revelt
2
我想在这个很棒的答案中添加额外的信息,NPM有一个开放的RFC来按顺序执行工作区命令,希望将来能够实现。在版本/发布方面,我创建了一个从Lerna派生出来的库,在其中只提取了2个命令(版本和发布),因为我想保留传统的变更日志,但我不想要Lerna的所有额外内容,您可以查看ws-conventional-version-roller,该库本身是有意作为NPM Workspace创建的。 - ghiscoding

0

从管理角度来看,是的。因为它可以处理诸如更改报告之类的事情。

然而,如果你只想拥有一个单一的代码库,并且你知道依赖项的构建顺序,而不是依赖于packages/*,那么就没有必要使用它。在大多数情况下,您可以简单地使用以下顺序进行构建,并且在真正需要lerna和依赖项之前摆脱它们。

yarn install --frozen-lockfile
yarn workspaces run prepare
yarn workspaces run test

旁注:问题涉及NPM,而您提供的答案是关于Yarn的,这与原始问题并不完全相关。 - ghiscoding

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