Yarn + Lerna + Angular Libs = 破坏出版?

Yarn + Lerna + Angular Libs = broken publishing?

再嗨!

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

在 packages/libraries 的每个 package.json 中,我们有类似的东西:

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

Yarn 为工作区工作的方式是 yarn install,做它做的事。因为我们使用工作区,它会创建 符号链接 到包。例如,如果我们有一个名为 @foo/bar 的包,在顶层 node_modules 中,我们将 node_modules/@foo/bar 是指向 libs/foo-bar.

的符号链接

Yarn Workspaces 一切都很好,但 node_modules/@foo/bar 中的东西还没有准备好发布。首先,我们需要使用 Angular CLI 的编译器构建包。

我们使用 package.json 中已经提到的 prepublishOnly 脚本实现了这一点。

有效的是所有需要构建的包。流程是:

  1. yarn install - symlink/workspace 魔法。
  2. lerna publish --contents dist - 做 monorepo 魔术。 Lerna 将看到所有包都进行了修改,并且 运行 prepublishOnly 跨越所有包。这样,node_modules/@foo 中的内容将是“合法的”NPM 包(Angular CLI 构建库的输出)

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

  1. yarn install - 执行 symlink/workspace 魔法。 node_modules/@foo 中的所有内容都将是 libs/<package-name> 的符号链接,此时,它们是源文件。不是 NPM 包
  2. lerna publish --contents dist - 开始...然后说“哦,只有包 A 发生了变化。所以让我 运行 反对它。” Lerna 将失败,因为 node_modules 中的其他包不是合法的 NPM 包。

我需要弄清楚如何:

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

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

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

发布时始终构建所有包

在您的根目录中 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" );

});