Skip to main content

版本及发布

¥Version and Publish

Lerna 可以增加包的版本以及将包发布到 NPM,并且它提供了多种选项来确保可以适应任何工作流程。

¥Lerna can increment your package's versions as well as publish your packages to NPM, and it provides a variety of options to make sure any workflow can be accommodated.

为了展示 Lerna 如何做到这一点,我们将看看 这个存储库

¥To show how Lerna does it, we will look at this repository.

如果你通过实践学习得更好,请克隆存储库并继续操作。

¥If you learn better by doing, clone the repo and follow along.

该存储库包含三个包或项目:

¥The repo contains three packages or projects:

  • header(React 组件库)

    ¥header (a library of React components)

  • footer(React 组件库)

    ¥footer (a library of React components)

  • remixapp(使用 Remix 框架编写的应用,依赖于 headerfooter

    ¥remixapp (an app written using the Remix framework which depends on both header and footer)

我们将发布 headerfooter 包。

¥We are going to publish the header and the footer packages.

仅发布项目的子集是很常见的。有些项目可以是私有的(例如,仅用于测试),有些可以是演示应用。在此存储库中,remixapp 不是 "private",意思是不希望人们看到源文件,它只是使用 "private": true 设置以免发布到 NPM。

¥It's common to publish only a subset of the projects. Some projects can be private (e.g., used only for tests), some can be demo apps. In this repo, remixapp isn't "private" in the sense of not wanting people to see the source files, it is just using the "private": true setting in order to not get published to NPM.

版本控制

¥Versioning

Lerna 附带了 version 命令,允许你增加包的版本号、提交更改并相应地标记它们。

¥Lerna comes with a version command that allows you to increment your package's version number, commit the changes and tag them accordingly.

lerna version --no-private

你会得到以下输出:

¥you'll get the following output:

lerna notice cli v5.1.2
lerna info current version 1.0.0
lerna info Assuming all packages changed
? Select a new version (currently 1.0.0) (Use arrow keys)
❯ Patch (1.0.1)
Minor (1.1.0)
Major (2.0.0)
Prepatch (1.0.1-alpha.0)
Preminor (1.1.0-alpha.0)
Premajor (2.0.0-alpha.0)
Custom Prerelease
Custom Version
信息

请注意,通过传递 --no-private,我们排除了 package.json 文件中标记为 private 的所有包。

¥Note that by passing --no-private we exclude all packages that are marked private in their package.json file.

Lerna 检测当前软件包,识别当前版本并建议选择下一个版本。请注意,你也可以像 lerna version 1.0.0 一样直接传递 semver 冲突。更多关于 版本文档详细信息 的信息。一旦选择了给定版本,Lerna 就会使用版本号更新 package.json,提交更改,添加相应的版本标签(例如 v1.0.0),并将提交和标签推送到远程存储库。

¥Lerna detects the current packages, identifies the current version and proposes the next one to choose. Note, you can also pass a semver bump directly like lerna version 1.0.0. More on the version docs details. Once a given version is chosen, Lerna updates the package.json with the version number, commits the change, adds a corresponding version tag (e.g. v1.0.0) and pushes the commit and the tag to the remote repository.

packages/footer/package.json
{
"name": "footer",
"version": "1.0.1",
"main": "dist/index.js",
...
}

请注意,上述操作不会将包推送到任何 NPM 存储库。如果我们还希望 Lerna 负责发布过程,我们可以使用 lerna publish

¥Note the above operation does not push the package to any NPM repository. If instead we also want Lerna to take care of the publishing process, we can use lerna publish instead.

信息

Lerna 使用 lerna.json 中的 version 属性来确定当前使用的版本

¥Lerna uses the version property in lerna.json to determine the currently used version

发布到 NPM

¥Publishing to NPM

如果我们运行

¥If we run

lerna publish --no-private

Lerna 执行版本递增工作流程(与 lerna version 相同),此外还将包推送到 NPM。你应该得到以下输出:

¥Lerna executes the version incrementing workflow (same as lerna version) and in addition also pushes the packages to NPM. You should get the following output:

Terminal Output
lerna notice cli v5.1.2
lerna info current version 1.0.0
lerna info Assuming all packages changed
? Select a new version (currently 1.0.0) Patch (1.0.1)

Changes:
- footer: 1.0.0 => 1.0.1
- header: 1.0.0 => 1.0.1

? Are you sure you want to publish these packages? Yes
lerna info execute Skipping releases
lerna info git Pushing tags...
lerna info publish Publishing packages to npm...
...
lerna success published header 1.0.1
...
lerna success published footer 1.0.1
...
Successfully published:
- footer@1.0.1
- header@1.0.1
lerna success published 2 packages

from-package

Lerna 确定要发布哪些包的另一种方法是使用 from-package。Lerna 会将存储库中每个包的版本与发布到 npm 的版本进行比较。对于版本高于已发布版本的每个包,Lerna 都会将该包发布到 npm。

¥Another way Lerna can determine which packages to publish is with from-package. Lerna will compare the version of every package in the repository with the version of it that is published to npm. For each package that has a version that is greater than the published version, Lerna will publish that package to npm.

此模式不明确要求包已使用 lerna version 进行版本控制,这对于拥有自己的版本控制脚本的工作区来说非常有用。

¥This mode does not explicitly require that the packages have been versioned with lerna version, which makes it great for workspaces that have their own versioning scripts.

lerna publish from-package
信息

Lerna 总是使用 npm 来发布包。如果你使用 npm 以外的包管理器,则仍然需要向 .npmrc 添加适当的发布配置,即使 npmClientlerna.json 中设置为 npm 以外的其他内容。

¥Lerna always uses npm to publish packages. If you use a package manager other than npm, you will need to still add the appropriate publishing configuration to .npmrc, even if npmClient is set to something other than npm in lerna.json.

版本控制策略

¥Versioning strategies

Lerna 允许你使用以下两种模式之一来管理你的项目:固定或独立。

¥Lerna allows you to manage your project using one of two modes: Fixed or Independent.

固定/锁定模式(默认)

¥Fixed/Locked mode (default)

固定模式 Lerna 项目在单一版本线上运行。该版本保存在项目根目录下的 lerna.json 文件中的 version 密钥下。当你运行 lerna publish 时,如果自上次发布以来软件包已更新,它将更新为你要发布的新版本。这意味着你仅在需要时才发布包的新版本。

¥Fixed mode Lerna projects operate on a single version line. The version is kept in the lerna.json file at the root of your project under the version key. When you run lerna publish, if a package has been updated since the last time a release was made, it will be updated to the new version you're releasing. This means that you only publish a new version of a package when you need to.

注意:如果你的主要版本为零,则所有更新都是 考虑打破。因此,使用主版本 0 运行 lerna publish 并选择任何非预发布版本号将导致所有包发布新版本,即使自上次发布以来并非所有包都发生了更改。

¥Note: If you have a major version zero, all updates are considered breaking. Because of that, running lerna publish with a major version zero and choosing any non-prerelease version number will cause new versions to be published for all packages, even if not all packages have changed since the last release.

如果你想自动将所有包版本绑定在一起,请使用此选项。这种方法的一个问题是,任何包中的重大更改都将导致所有包都有新的主要版本。

¥Use this if you want to automatically tie all package versions together. One issue with this approach is that a major change in any package will result in all packages having a new major version.

同步版本

¥Synchronized Versions

Lerna 只会对自上一版本以来发生更改的软件包进行版本控制和发布,从而导致软件包版本随着时间的推移而发生变化。为了防止这种情况,请将 --force-publish 选项与 lerna version 一起使用。这将迫使 Lerna 始终对所有软件包进行版本控制,无论它们自上一个版本以来是否发生了更改。然后由 lerna publish from-git 将它们全部发布到注册表中。因此,所有软件包版本将与 lerna.json 中的版本保持同步。

¥Lerna will only version and publish packages that have changed since the previous release, causing package versions to drift apart over time. To prevent this, use the --force-publish option with lerna version. This will force Lerna to always version all packages, regardless of if they have changed since the previous release. Then they will all be published to the registry by lerna publish from-git. As a result, all package versions will stay synchronized to the version in lerna.json.

独立模式

¥Independent mode

npx lerna init --independent

独立模式 Lerna 项目允许维护者相互独立地增加包版本。每次发布时,你都会收到每个已更改的包的提示,以指定它是补丁、次要更改、主要更改还是自定义更改。

¥Independent mode Lerna projects allows maintainers to increment package versions independently of each other. Each time you publish, you will get a prompt for each package that has changed to specify if it's a patch, minor, major or custom change.

独立模式允许你更具体地更新每个包的版本,并且对于一组组件有意义。将此模式与 semantic-release 之类的模式结合起来会减轻痛苦。(Atlassian/lerna-语义发布 已经有这方面的工作)。

¥Independent mode allows you to more specifically update versions for each package and makes sense for a group of components. Combining this mode with something like semantic-release would make it less painful. (There is work on this already at atlassian/lerna-semantic-release).

设置 lerna.jsonindependent 中的 version 键以独立模式运行。

¥Set the version key in lerna.json to independent to run in independent mode.