Yarn + Lerna + Angular Libs = 破坏出版?
Yarn + Lerna + Angular Libs = broken publishing?
再嗨!
这是交易,我们有一个 monorepo。我们将 Lerna 和 Yarn 与一堆 Angular 库一起使用。
在 packages/libraries 的每个 package.json 中,我们有类似的东西:
"prepublishOnly": "yarn build <library name goes here>"
Yarn 为工作区工作的方式是 yarn install
,做它做的事。因为我们使用工作区,它会创建 符号链接 到包。例如,如果我们有一个名为 @foo/bar
的包,在顶层 node_modules
中,我们将 node_modules/@foo/bar
是指向 libs/foo-bar
.
的符号链接
Yarn Workspaces 一切都很好,但 node_modules/@foo/bar
中的东西还没有准备好发布。首先,我们需要使用 Angular CLI 的编译器构建包。
我们使用 package.json
中已经提到的 prepublishOnly
脚本实现了这一点。
有效的是所有需要构建的包。流程是:
yarn install
- symlink/workspace 魔法。
lerna publish --contents dist
- 做 monorepo 魔术。 Lerna 将看到所有包都进行了修改,并且 运行 prepublishOnly
跨越所有包。这样,node_modules/@foo
中的内容将是“合法的”NPM 包(Angular CLI 构建库的输出)
问题是当单个库有修改时。
yarn install
- 执行 symlink/workspace 魔法。 node_modules/@foo
中的所有内容都将是 libs/<package-name>
的符号链接,此时,它们是源文件。不是 NPM 包
lerna publish --contents dist
- 开始...然后说“哦,只有包 A 发生了变化。所以让我 运行 反对它。” Lerna 将失败,因为 node_modules
中的其他包不是合法的 NPM 包。
我需要弄清楚如何:
- 在进行发布时始终构建所有包或
- 在构建过程中以某种方式使用 NPM 注册表中的包
我觉得我在某处遗漏了一些简单的东西。
如果有例子可以帮助解释,请询问。
发布时始终构建所有包
在您的根目录中 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" );
});
再嗨!
这是交易,我们有一个 monorepo。我们将 Lerna 和 Yarn 与一堆 Angular 库一起使用。
在 packages/libraries 的每个 package.json 中,我们有类似的东西:
"prepublishOnly": "yarn build <library name goes here>"
Yarn 为工作区工作的方式是 yarn install
,做它做的事。因为我们使用工作区,它会创建 符号链接 到包。例如,如果我们有一个名为 @foo/bar
的包,在顶层 node_modules
中,我们将 node_modules/@foo/bar
是指向 libs/foo-bar
.
Yarn Workspaces 一切都很好,但 node_modules/@foo/bar
中的东西还没有准备好发布。首先,我们需要使用 Angular CLI 的编译器构建包。
我们使用 package.json
中已经提到的 prepublishOnly
脚本实现了这一点。
有效的是所有需要构建的包。流程是:
yarn install
- symlink/workspace 魔法。lerna publish --contents dist
- 做 monorepo 魔术。 Lerna 将看到所有包都进行了修改,并且 运行prepublishOnly
跨越所有包。这样,node_modules/@foo
中的内容将是“合法的”NPM 包(Angular CLI 构建库的输出)
问题是当单个库有修改时。
yarn install
- 执行 symlink/workspace 魔法。node_modules/@foo
中的所有内容都将是libs/<package-name>
的符号链接,此时,它们是源文件。不是 NPM 包lerna publish --contents dist
- 开始...然后说“哦,只有包 A 发生了变化。所以让我 运行 反对它。” Lerna 将失败,因为node_modules
中的其他包不是合法的 NPM 包。
我需要弄清楚如何:
- 在进行发布时始终构建所有包或
- 在构建过程中以某种方式使用 NPM 注册表中的包
我觉得我在某处遗漏了一些简单的东西。
如果有例子可以帮助解释,请询问。
发布时始终构建所有包
在您的根目录中 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" );
});