Yarn + Lerna + Angular Libs = 出版失败?

Posted

技术标签:

【中文标题】Yarn + Lerna + Angular Libs = 出版失败?【英文标题】:Yarn + Lerna + Angular Libs = broken publishing? 【发布时间】:2021-01-11 07:33:26 【问题描述】:

你好!

这是交易,我们有一个 monorepo。我们将 Lerna 和 Yarn 与一堆 Angular 库一起使用。

在包/库的每个 package.json 中,我们都有类似的内容:

"prepublishOnly": "yarn build <library name goes here>"

Yarn 在工作空间中的工作方式是 yarn install,做它的工作。因为我们使用工作空间,所以它会为包创建 symlinks。例如,如果我们有一个名为@foo/bar 的包,在***node_modules 中,我们将node_modules/@foo/bar 成为libs/foo-bar 的符号链接。

Yarn Workspaces 一切都很好,很漂亮,除了 node_modules/@foo/bar 中的内容还没有准备好发布。首先,我们需要使用 Angular CLI 的编译器来构建包。

我们通过package.json 中已经提到的prepublishOnly 脚本来实现这一点。

当需要构建所有包时起作用。流程如下:

    yarn install - 符号链接/工作区有什么魔力。 lerna publish --contents dist - monorepo 有什么魔力。 Lerna 将看到所有包都已修改,并在所有包中运行prepublishOnly。这样,node_modules/@foo 中的内容将是“合法”的 NPM 包(Angular CLI 构建库的输出)

问题是当单个库有修改时。

    yarn install - 符号链接/工作区是否具有魔力。 node_modules/@foo 中的所有内容都将是指向 libs/<package-name> 的符号链接,此时它们是源文件。不是 NPM 包 lerna publish --contents dist - 开始......然后说“哦,只有包 A 发生了变化。所以让我来反对它。”由于node_modules 中的其他包不是合法的 NPM 包,Lerna 将失败。

我需要弄清楚如何:

    在发布时始终构建所有包或 在构建过程中以某种方式使用 NPM 注册表中的包

我觉得我在某处遗漏了一些简单的东西。

如果有我可以提供帮助解释的例子,请询问。

【问题讨论】:

【参考方案1】:

在发布时始终构建所有包

在您的根 package.json 中(考虑到您已将 lerna 作为开发依赖项)


 "scripts": 
     "publish-ci": "lerna run build && lerna publish --content dist"
  

在您的 library1 包中

 "scripts": 
     "build": "yarn build library1"
  

现在您可以在根文件夹上运行yarn publish-ci,所有内容都将被构建和发布。

您也可以使用lerna publish --from-package 标志仅发布更改的包。

在构建过程中以某种方式使用 NPM 注册表中的包

在这里,您需要 lerna 仅更改包,而不是用于发布,这是一种 hacky 方法

在你的根 package.json 中


 "scripts": 
     "publish-ci": "node custom.publish.js"
  

在 custom.publish.js 中


var  execSync  = require("child_process");
let packagesChangedString = execSync("yarn lerna changed --toposort --json --loglevel silent").toString();
let packageChanged = JSON.parse(packagesChangedString.substring(packagesChangedString.indexOf("["), packagesChangedString.lastIndexOf("]") + 1));
console.log(packageChanged);

packageChanged.forEach(changed => 
    // exec npm publish manually without using lerna for publishing. 
    execSync("cd " + changed.location + " && npm publish" );

);

【讨论】:

以上是关于Yarn + Lerna + Angular Libs = 出版失败?的主要内容,如果未能解决你的问题,请参考以下文章

Lerna、yarn 和 Typescript:找不到模块或其对应的类型声明

使用 yarn 工作区和 lerna 优先构建顺序

Yarn workspace + lerna 在每个子包中创建 node_modules

如何在 Lerna + Yarn Workspaces repo 中安装 npm 包?

基于 Yarn WorkSpace + Lerna + OrangeCI 搭建 Typescript Monorepo 项目实践

lerna+yarn workspace+monorepo项目的最佳实践