{"meta":{"title":"发布 Node.js 包","intro":"在本教程中，你将了解如何在持续集成 (CI) 工作流中将 Node.js 包发布到注册表。","product":"GitHub Actions","breadcrumbs":[{"href":"/zh/actions","title":"GitHub Actions"},{"href":"/zh/actions/tutorials","title":"教程"},{"href":"/zh/actions/tutorials/publish-packages","title":"发布软件包"},{"href":"/zh/actions/tutorials/publish-packages/publish-nodejs-packages","title":"发布 Node.js 包"}],"documentType":"article"},"body":"# 发布 Node.js 包\n\n在本教程中，你将了解如何在持续集成 (CI) 工作流中将 Node.js 包发布到注册表。\n\n## 简介\n\n本指南介绍如何创建一个工作流程，以在持续集成 (CI) 测试通过后将 Node.js 包发布到 GitHub Packages 和 npm 注册表。\n\n## 先决条件\n\n建议基本了解工作流程配置选项和如何创建工作流程文件。 有关详细信息，请参阅“[撰写工作流程](/zh/actions/learn-github-actions)”。\n\n有关为 Node.js 项目创建 CI 工作流的详细信息，请参阅“[构建和测试 Node.js](/zh/actions/automating-builds-and-tests/building-and-testing-nodejs)”。\n\n你可能还发现基本了解以下内容是有帮助的：\n\n* [在 npm 注册表上工作](/zh/packages/working-with-a-github-packages-registry/working-with-the-npm-registry)\n* [在变量中存储信息](/zh/actions/learn-github-actions/variables)\n* [在 GitHub Actions 中使用机密](/zh/actions/security-guides/using-secrets-in-github-actions)\n* [在工作流中使用 GITHUB\\_TOKEN 进行身份验证](/zh/actions/security-guides/automatic-token-authentication)\n\n## 关于包配置\n\n```\n          `name` 文件中的 `version` 和 `package.json` 字段创建一个唯一标识符，注册表使用该标识符将包链接到注册表。 可以通过在 `description` 文件中包含一个 `package.json` 字段来添加软件包列表页面的摘要。 有关详细信息，请参阅 npm 文档中的“[创建 package.json 文件](https://docs.npmjs.com/creating-a-package-json-file)”和“[创建 Node.js 模块](https://docs.npmjs.com/creating-node-js-modules)”。\n```\n\n当本地 `.npmrc` 文件存在并指定了 `registry` 值时，`npm publish` 命令将使用在 `.npmrc` 文件中配置的注册表。 可使用 `setup-node` 操作在运行器上创建本地 `.npmrc` 文件以配置默认注册表和范围。 `setup-node` 操作也接受身份验证令牌作为输入，用于访问私人注册表或发布节点包。 有关详细信息，请参阅 [`setup-node`](https://github.com/actions/setup-node/)。\n\n可以使用 `setup-node` 操作指定运行器上安装的 Node.js 版本。\n\n如果在工作流中添加步骤来配置 `publishConfig` 文件中的 `package.json` 字段，则无需使用 `setup-node` 操作指定 registry-url，但是只能将包发布到一个注册表。 有关详细信息，请参阅 npm 文档中的“[publishConfig](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#publishconfig)”。\n\n## 发布包到 npm 注册表\n\n每次发布新版本时，都可以触发工作流来发布包。 当触发类型 `published` 的发布事件时，执行下例中的过程。 如果 CI 测试通过，该过程会将包上传到 npm 注册表。 有关详细信息，请参阅“[管理存储库中的发行版](/zh/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release)”。\n\n要在您的工作流程中针对 npm 注册表执行经过身份验证的操作，您需要将 npm 身份验证令牌存储为机密。 例如，创建名为 `NPM_TOKEN` 的存储库机密。 有关详细信息，请参阅“[在 GitHub Actions 中使用机密](/zh/actions/security-guides/using-secrets-in-github-actions)”。\n\n默认情况下，npm 使用 `name` 文件的 `package.json` 字段来确定已发布包的名称。 当发布到全局命名空间时，您只需要包含包名称。 例如，将名为 `my-package` 的包发布到 `https://www.npmjs.com/package/my-package`。\n\n如果要发布包含范围前缀的包，请在 `package.json` 文件的名称中包含范围。 例如，如果 npm 范围前缀是“octocat”并且包名称是“hello-world”，那么 `name` 文件中的 `package.json` 应为 `@octocat/hello-world`。 如果 npm 包使用范围前缀并且包是公共的，则需要使用选项 `npm publish --access public`。 这是 npm 需要用来防止有人无意中发布私有包的选项。\n\n如果要发布具有证明的包，请将 `--provenance` 标志包含在命令 `npm publish` 中。 这样，你就可以公开且可验证地确定包的生成位置和方式，从而增加使用包的人员的供应链安全性。 有关详细信息，请参阅 npm 文档中的[生成来源语句](https://docs.npmjs.com/generating-provenance-statements)。\n\n此示例将 `NPM_TOKEN` 机密存储在 `NODE_AUTH_TOKEN` 环境变量中。 当 `setup-node` 操作创建 `.npmrc` 文件时，会引用来自 `NODE_AUTH_TOKEN` 环境变量的令牌。\n\n```yaml copy\nname: Publish Package to npmjs\non:\n  release:\n    types: [published]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      id-token: write\n    steps:\n      - uses: actions/checkout@v5\n      # Setup .npmrc file to publish to npm\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://registry.npmjs.org'\n      - run: npm ci\n      - run: npm publish --provenance --access public\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n```\n\n在上面的示例中，`setup-node` 操作在运行器上创建了一个具有以下内容的 `.npmrc` 文件：\n\n```shell\n//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}\nregistry=https://registry.npmjs.org/\nalways-auth=true\n```\n\n请注意，需要在 `registry-url` 中将 `https://registry.npmjs.org/` 设置为 `setup-node` 才能正确配置凭据。\n\n## 将包发布到 GitHub Packages\n\n每次发布新版本时，都可以触发工作流来发布包。 当触发类型 `published` 的发布事件时，执行下例中的过程。 如果 CI 测试通过，该过程会将包上传到 GitHub Packages。 有关详细信息，请参阅“[管理存储库中的发行版](/zh/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release)”。\n\n### 配置目标仓库\n\n使用 `repository` 键将包链接到 GitHub Packages 是可选操作。 如果你选择不在 `repository` 文件中提供 `package.json` 密钥，则你的包在发布时不会链接到存储库，但你可以选择稍后将包连接到存储库。\n\n如果您在 `repository` 文件中确实提供了 `package.json` 密钥，那么该密钥中的存储库将用作 GitHub Packages 的目标 npm注册表。 例如，发布以下 `package.json` 结果将导致名为 `my-package` 的包发布到 `octocat/my-other-repo` GitHub 存储库。\n\n```json\n{\n  \"name\": \"@octocat/my-package\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/octocat/my-other-repo.git\"\n  },\n}\n```\n\n### 向目标仓库进行认证\n\n要在工作流中对 GitHub Packages 注册表执行经过身份验证的操作，可以使用 `GITHUB_TOKEN`。 每当工作流中的作业开始时，`GITHUB_TOKEN` 机密都会设置为存储库的访问令牌。 应在工作流文件中设置此访问令牌的权限，以授予 `contents` 权限的读取访问权限，并授予 `packages` 权限的写入访问权限。 有关详细信息，请参阅“[在工作流中使用 GITHUB\\_TOKEN 进行身份验证](/zh/actions/security-guides/automatic-token-authentication)”。\n\n如果要将包发布到其他存储库，必须使用对目标存储库中的包具有写入权限的 personal access token (classic)。 有关详细信息，请参阅 [管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) 和 [在 GitHub Actions 中使用机密](/zh/actions/security-guides/using-secrets-in-github-actions)。\n\n### 示例工作流\n\n此示例将 `GITHUB_TOKEN` 机密存储在 `NODE_AUTH_TOKEN` 环境变量中。 当 `setup-node` 操作创建 `.npmrc` 文件时，会引用来自 `NODE_AUTH_TOKEN` 环境变量的令牌。\n\n```yaml copy\nname: Publish package to GitHub Packages\non:\n  release:\n    types: [published]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n    steps:\n      - uses: actions/checkout@v5\n      # Setup .npmrc file to publish to GitHub Packages\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://npm.pkg.github.com'\n          # Defaults to the user or organization that owns the workflow file\n          scope: '@octocat'\n      - run: npm ci\n      - run: npm publish\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n```\n          `setup-node` 操作在运行器上创建一个 `.npmrc` 文件。 当对 `scope` 操作使用 `setup-node` 输入时，`.npmrc` 文件包含范围前缀。 默认情况下，`setup-node` 操作会将 `.npmrc` 文件中的范围设置为包含该工作流文件的帐户。\n```\n\n```shell\n//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}\n@octocat:registry=https://npm.pkg.github.com\nalways-auth=true\n```\n\n## 使用 Yarn 发布软件包\n\n如果您使用 Yarn 包管理器，可以使用 Yarn 安装和发布包。\n\n```yaml copy\nname: Publish Package to npmjs\non:\n  release:\n    types: [published]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n      # Setup .npmrc file to publish to npm\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://registry.npmjs.org'\n          # Defaults to the user or organization that owns the workflow file\n          scope: '@octocat'\n      - run: yarn\n      - run: yarn npm publish // for Yarn version 1, use `yarn publish` instead\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n```\n\n要在发布期间进行注册表身份验证，请确保在 `yarnrc.yml` 文件中也定义了你的身份验证令牌。 有关详细信息，请参阅 Yarn 文档中的[设置](https://yarnpkg.com/configuration/yarnrc#npmAuthToken)一文。"}