24

我正在尝试使用 Lerna 设置我的 monorepo。该计划是通过提取应该是他们自己的包的代码块来重构现有项目。我已经运行了lerna init,我当前的设置如下所示:

project/
  packages/
    new-refactored-package/
      package.json
    prior-existing-project/
      package.json
        { "dependencies" : { "new-refactored-package" : "latest" } }
  package.json
    {
      "devDependencies": {
        "lerna": "^2.0.0-rc.5"
      }
    }
  lerna.json
    {
      "lerna": "2.0.0-rc.5",
      "packages": [
        "packages/*"
      ],
      "version": "0.0.0"
    }

我的理解是,lerna bootstrap此时应该位于项目中package1并将其符号链接到prior-existing-project. /node_modules/new-refactored-package/来自lerna 的自述文件

引导当前 Lerna 存储库中的包。安装它们的所有依赖项并链接任何交叉依赖项。

运行时,此命令将:

  • npm 安装每个包的所有外部依赖项。
  • 将所有相互依赖的 Lerna 包符号链接在一起。
  • npm 预发布所有引导程序包。

但是,当我运行它时,lerna 会尝试npm install new-refactored-package

npm 错误!404 注册表在https://registry.npmjs.org/new-refactored-package上为 GET 返回 404

我是不是误会了?我是否首先必须将依赖的包发布到npm

4

5 回答 5

17

要求

为了lerna在运行本地包时对本地包进行符号链接lerna bootstrap,本地包必须有一个name version匹配的。每当lerna无法将依赖项与本地包匹配时,它将尝试从注册表安装它。

所以要保证依赖包有一个可以被dependant中的semver版本匹配的版本。

例子

{

  name: "@my-name/dependency",
  version: "1.2.0"
}
{
  name: "@my-name/dependant",
  dependencies: {
    "@my-name/dependency": "<VERSION>"
  }
}

@my-name/dependencyVERSIONis 1.2.0^1.0.01.X.X或时将被符号链接*。但是,当使用与本地包不匹配的范围时,例如1.0.0or ^0.0.0,它将尝试在 npm 注册表中解决它并显示错误,例如 404 Not Found - GET https://registry.npmjs.org/@my-name%2fdependency - Not found.

latest

在问题中解释的实际场景中,实际问题是版本被指定为latest,虽然很容易认为这是可用的最新版本latest的通用术语,但实际上它是默认应用于所有新版本的.npm-dist-tag

如果您查看react(单击版本)之类的包,您可以看到除了 之外latest,它们还部署带有标签的版本nextcanaryunstable.

您未发布的包没有任何标签,因为它们已应用于发布,因此latest不会匹配,这意味着lerna将尝试远程解决它,失败为404.

这在命令文档的注释中被指出为其中一个问题bootstrap

  • 当 repo 中的同名包不满足包中的依赖版本时,它将像往常一样被npm installed(或ed)。yarn
  • Dist-tags,如latest,不满足semver范围。
  • 循环依赖会导致循环符号链接,这可能会影响您的编辑器/IDE。

解决方案

如果您想匹配任何可用的版本,推荐的路径是将版本设置为"*". 这将匹配任何版本,因此将始终使用本地版本,因为本地包具有指定的version字段。

{ 
  "dependencies": { 
    "new-refactored-package" : "*"
  }
}

alpha,rcbeta

Even与标记为预发布*的版本匹配,因此如果您为本地软件包提供类似0.0.1-alpha.0, 或的版本1.0.0-rc.3,它也不会在本地进行符号链接

private: true

虽然它不影响lerna bootstrap,但值得一提的是,您不想发布的包应该始终具有private: true;. 这将确保lerna publish不会发布它。

于 2019-03-03T11:53:46.553 回答
7

lerna bootstrap如果可用,将对包进行符号链接而不是安装。

就您而言,我认为 lerna 找不到正确的versionorname包。

这是我在项目中所做的...

project
- packages/
    - a_pkg
        - package.json {
            "name": "@scope/a_pkg",
            "version": "0.0.1",
            "private": true
            /// opt out
        }
    - b_pkg
        - package.json {
            "name": "@scope/b_pkg",
            "version": "0.0.1",
            "private": true,
            "dependencies": {
              "@scope/a_pkg": "^0"
            },
            /// opt out
        }
- package.json
- lerna.json {
    "packages": [
        "packages/*"
    ],
    /// opt out
}
于 2017-07-20T10:00:54.640 回答
1

尝试使用“lerna add <DEPENDENCY_NAME>”命令安装依赖项,而不是手动添加依赖项。这将自动添加本地版本(如果可用)

于 2021-10-08T05:16:15.070 回答
1

lerna bootstrap将检查您在package.json或中指定的软件包版本package-lock.json

既然你还没有发表你的作品,我会尝试--force-localbootstrap命令上使用。

lerna bootstrap --force-local

于 2019-12-30T06:07:01.470 回答
-2

package.json 中的包名称必须与 /packages 文件夹中的文件夹名称匹配。

(基本上是@kp_ping 所说的)

于 2018-07-20T09:27:51.683 回答