【问题标题】:Yarn + Lerna + Angular Libs = broken publishing?Yarn + Lerna + Angular Libs = 出版失败?
【发布时间】: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 脚本来实现这一点。

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

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

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

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

我需要弄清楚如何:

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

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

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

【问题讨论】:

    标签: angularjs yarnpkg lerna


    【解决方案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" );
    
    });
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-15
      • 1970-01-01
      • 2022-01-11
      • 2022-07-23
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2019-02-08
      相关资源
      最近更新 更多