使用Lerna与未发布的包

问题描述 投票:11回答:3

我正在尝试用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's readme

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

运行时,此命令将:

  • npm安装每个包的所有外部依赖项。
  • 将所有相互依赖的Lerna软件包汇集在一起​​。
  • npm预先发布所有自举包。

然而,当我运行它时,lerna尝试改为npm install new-refactored-package

错误的ERR! 404注册表在https://registry.npmjs.org/new-refactored-package上返回404获取GET

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

lerna
3个回答
7
投票

lerna bootstrap将使用符号链接包而不是安装(如果可用)。

在你的情况下,我认为lerna无法找到正确的包装versionname

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

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
}

2
投票

Requirements

对于lerna在运行lerna bootstrap时使用符号链接本地包,本地包必须具有匹配的nameversion。每当lerna无法将依赖项与本地程序包匹配时,它将尝试从注册表中安装它。

因此,请确保依赖包具有可由依赖项中的semver版本匹配的版本。

Example

{

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

@my-name/dependencyVERSION1.2.0^1.0.01.X.X时,*将被符号化。但是当使用与本地包不匹配的范围时,如1.0.0^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失败。

这被称为Notes命令文档的bootstrap中的一个陷阱。

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

Solution

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

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

alpha, rc or beta

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

private: true

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


-2
投票

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

(基本上是@kp_ping所说的)

© www.soinside.com 2019 - 2024. All rights reserved.