将Lerna与未发布的软件包一起使用

Using Lerna with unpublished packages

我正在尝试与Lerna建立我的monorepo。 计划是通过提取应属于自己的程序包的代码块来重构现有项目。 我已经运行了lerna init,当前的设置如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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的自述文件中:

Bootstrap the packages in the current Lerna repo. Installs all of their dependencies and links any cross-dependencies.

When run, this command will:

  • npm install all external dependencies of each package.
  • Symlink together all Lerna packages that are dependencies of each other.
  • npm prepublish all bootstrapped packages.

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

npm ERR! 404 Registry returned 404 for GET on https://registry.npmjs.org/new-refactored-package

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


要求

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

因此,请确保依赖项包的版本可以与依赖项中的semver版本匹配。

1
2
3
4
5
{

  name:"@my-name/dependency",
  version:"1.2.0"
}
1
2
3
4
5
6
{
  name:"@my-name/dependant",
  dependencies: {
   "@my-name/dependency":"<VERSION>"
  }
}

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

bootstrap命令的文档注释中,这被视为陷阱之一。

  • When a dependency version in a package is not satisfied by a package of the same name in the repo, it will be npm installed (or yarned) like normal.
  • Dist-tags, like latest, do not satisfy semver ranges.
  • Circular dependencies result in circular symlinks which may impact your editor/IDE.

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

1
2
3
4
5
{
 "dependencies": {
   "new-refactored-package" :"*"
  }
}

alpha, rc or beta

Even * will not match versions that are marked as pre-release, so if you give your local package a version like 0.0.1-alpha.0, or 1.0.0-rc.3, it will also not be locally symlinked

private: true

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


如果可用,lerna bootstrap将符号链接软件包,而不是安装软件包。

在您的情况下,我认为lerna无法找到软件包的正确versionname

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
}


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

由于您尚未发布您的作品,因此我将尝试在bootstrap命令上使用--force-local

lerna bootstrap --force-local


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

(基本上是@kp_ping所说的)