我正在尝试用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 bootstrap
将使用符号链接包而不是安装(如果可用)。
在你的情况下,我认为lerna无法找到正确的包装version
或name
。
这是我在项目中所做的......
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
在运行lerna bootstrap
时使用符号链接本地包,本地包必须具有匹配的name
和version
。每当lerna
无法将依赖项与本地程序包匹配时,它将尝试从注册表中安装它。
因此,请确保依赖包具有可由依赖项中的semver版本匹配的版本。
{
name: "@my-name/dependency",
version: "1.2.0"
}
{
name: "@my-name/dependant",
dependencies: {
"@my-name/dependency": "<VERSION>"
}
}
当@my-name/dependency
是VERSION
,1.2.0
,^1.0.0
或1.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
之外,他们还部署了带有标签next
,canary
和unstable
的版本。
您未发布的包没有任何标签,因为它们在发布时应用,因此latest
将不匹配,这意味着lerna
将尝试远程解决它,与404
失败。
这被称为Notes命令文档的bootstrap
中的一个陷阱。
- 当repo中的同名包不满足包中的依赖版本时,它将像正常一样被
npm install
ed(或yarn
ed)。- 像
latest
这样的Dist-tag不满足semver范围。- 循环依赖会导致循环符号链接,这可能会影响您的编辑器/ IDE。
如果要匹配任何可用的版本,建议的路径是将版本设置为"*"
。这将匹配任何版本,因此将始终使用本地版本,因为本地包具有指定的version
字段。
{
"dependencies": {
"new-refactored-package" : "*"
}
}
alpha
,rc
orbeta
即使
*
也不会与标记为预发布的版本匹配,因此如果您为本地软件包提供类似0.0.1-alpha.0
或1.0.0-rc.3
的版本,它也不会在本地符号链接
private: true
虽然它不会影响lerna bootstrap
,但值得一提的是,您不想发布的软件包应始终具有private: true;
。这将确保lerna publish
不会发布它。
package.json中的包名称必须与/ packages文件夹中的文件夹名称匹配。
(基本上是@kp_ping所说的)