我对这个新的npm功能没有太多经验。 npm/RFCs写道:
首先,有一个解决问题的替代方案,就是使用非常流行的项目Lerna提供的一些功能。
另外,还有一个选择是仅支持安装(或者像Lerna称之为bootstrap)这个提案的方面,采用一个功能较少但仍然能实现基本目标的方法,即改善管理多个子包的用户体验。但根据在研究阶段收集到的所有反馈,这个选择对于参与其中的维护者社区来说远不如第一个选择受欢迎。
非常期待每一个答案和解释 :)
NPM自版本7开始支持工作区,已经有两个主要版本了。
通过工作区,npm i
/ npm ci
会处理嵌套包和符号链接。可以在单个或所有工作区上运行npm run
和npm exec
:
npm run test --workspace=a --workspace="name-from-package-dot-json"
npm run test --workspaces --if-present
话虽如此,lerna
比npm
或yarn
工作区提供了更多高级功能。
一个很好的例子是命令:lerna changed
,它会给出自上次标记发布以来发生变化的软件包列表,这对于CI/CD非常有帮助。欢迎您探索lerna提供的额外命令。
我写了一篇文章,深入介绍了配置,如果您想使用npm7进行单体库开发,那么不使用lerna绝对是一个选择,但您可能需要在CI/CD方面做更多工作,并自己添加一些开发脚本,这将影响嵌套的软件包。另外,在我看来,lerna更适合开发库而不是应用程序。
$ 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.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或其他工具。
conventionalCommits
)已经预先设置在“lerna”中,可以完全自动化生成变更日志。此外,要获得更细粒度的控制,您可以仅执行版本控制,并使用调用npm publish ||:
的简单脚本进行发布(如果没有要发布的内容,则不会以零代码退出;而npm不会让您发布未经修改的package.json文件)。 - revelt从管理角度来看,是的。因为它可以处理诸如更改报告之类的事情。
然而,如果你只想拥有一个单一的代码库,并且你知道依赖项的构建顺序,而不是依赖于packages/*
,那么就没有必要使用它。在大多数情况下,您可以简单地使用以下顺序进行构建,并且在真正需要lerna和依赖项之前摆脱它们。
yarn install --frozen-lockfile
yarn workspaces run prepare
yarn workspaces run test
npm run
和npm exec
现在得到支持,并可用于在多个工作区/包之间运行命令。 - trusktr