软件包仓库中的 npm 软件包

  1. Tier: 基础版, 专业版, 旗舰版
  2. Offering: JihuLab.com, 私有化部署

Node Package Manager (npm) 是 JavaScript 和 Node.js 的默认软件包管理工具。开发者使用 npm 分享和重用代码,管理依赖项,并简化项目工作流程。在极狐GitLab中,npm 软件包在软件开发生命周期中起着至关重要的作用。

有关 npm 软件包管理器客户端使用的特定 API 端点的文档,请参阅 npm API 文档

了解如何构建 npmyarn 软件包。

观看一个关于如何将 npm 软件包发布到极狐GitLab软件包仓库的视频演示

认证到软件包仓库#

你必须认证到软件包仓库才能从私有项目或私有群组发布或安装软件包。如果项目或群组是公共的,则不需要认证。如果项目是内部的,你必须是极狐GitLab实例上的注册用户。匿名用户不能从内部项目拉取软件包。

要进行认证,可以使用:

  1. 个人访问令牌,作用域设置为 api
  2. 部署令牌,作用域设置为 read_package_registrywrite_package_registry 或两者。
  3. CI/CD 作业令牌

如果你的组织使用两因素认证 (2FA),则必须使用作用域设置为 api 的个人访问令牌。如果你想用 CI/CD 流水线发布软件包,必须使用 CI/CD 作业令牌。更多信息,请查看令牌指南

不要使用此处未记录的其他认证方法。未记录的认证方法可能会在将来被删除。

使用 .npmrc 文件#

在与 package.json 相同的目录中创建或编辑 .npmrc 文件。在 .npmrc 文件中包含以下行:

shell
//<domain_name>/api/v4/projects/<project_id>/packages/npm/:_authToken="${NPM_TOKEN}"

绝不要将极狐GitLab令牌(或任何令牌)直接硬编码到 .npmrc 文件或任何其他可以提交到仓库的文件中。

例如:

shell
//<domain_name>/api/v4/packages/npm/:_authToken="${NPM_TOKEN}"

替换 <domain_name> 为你的域名。例如,gitlab.com

使用 npm config set#

执行以下操作:

shell
npm config set -- //<domain_name>/:_authToken=<token>

根据你的 npm 版本,你可能需要对 URL 做出更改:

  1. 在 npm 版本 7 或更早版本中,使用到端点的完整 URL。
  2. 在版本 8 及更高版本中,对于 _authToken 参数,你可以使用 URI 片段而不是完整 URL。群组特定端点不支持。

例如:

shell
npm config set -- //<domain_name>/api/v4/packages/npm/:_authToken=<token>

确保替换:

  • <domain_name> 为你的域名。例如,gitlab.com
  • <token> 为你的部署令牌、群组访问令牌、项目访问令牌或个人访问令牌。

设置仓库 URL#

要从极狐GitLab软件包仓库中发布或安装软件包,你需要配置 npm 使用正确的仓库 URL。配置方法和 URL 结构取决于你是在发布还是安装软件包。

在配置仓库 URL 之前,了解不同配置方法的作用域非常重要:

  • .npmrc 文件:配置是本地的,作用于包含该文件的文件夹。
  • npm config set 命令:此命令修改全局 npm 配置,影响你系统上运行的所有 npm 命令。
  • package.json 中的 publishConfig:此配置特定于软件包,仅在发布该软件包时适用。

运行 npm config set 会更改全局 npm 配置。此更改会影响你系统上运行的所有 npm 命令,而不管当前工作目录是什么。使用此方法时要小心,尤其是在共享系统上。

发布软件包#

发布软件包时,使用项目端点:

shell
https://gitlab.example.com/api/v4/projects/<project_id>/packages/npm/

gitlab.example.com 替换为你的极狐GitLab实例的域名,将 <project_id> 替换为你的项目 ID。要配置此 URL,请使用以下方法之一:

在项目根目录中创建或编辑 .npmrc 文件:

plaintext
@scope:registry=https://gitlab.example.com/api/v4/projects/<project_id>/packages/npm/ //gitlab.example.com/api/v4/projects/<project_id>/packages/npm/:_authToken="${NPM_TOKEN}"

@scope 替换为你的软件包的作用域。

安装软件包#

当你安装软件包时,你可以使用项目、群组或实例端点。URL 结构相应地变化。要配置这些 URL,请使用以下方法之一:

在项目根目录中创建或编辑 .npmrc 文件。根据你的需求使用适当的 URL:

  • 对于项目:

    shell
    @scope:registry=https://gitlab.example.com/api/v4/projects/<project_id>/packages/npm/
  • 对于群组:

    shell
    @scope:registry=https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/npm/
  • 对于实例:

    shell
    @scope:registry=https://gitlab.example.com/api/v4/packages/npm/

替换 gitlab.example.com<project_id><group_id>@scope 为你的极狐GitLab实例和软件包的适当值。

在你配置仓库 URL 后,你可以认证到软件包仓库。

发布到极狐GitLab软件包仓库#

要将 npm 软件包发布到极狐GitLab软件包仓库,你必须进行认证

命名约定#

根据软件包的安装方式,你可能需要遵守命名约定。

你可以使用三个 API 端点之一来安装软件包:

  1. 实例:当你在不同的极狐GitLab群组或它们自己的命名空间中有许多 npm 软件包时使用。
  2. 群组:当你在同一群组或子群组下的不同项目中有许多 npm 软件包时使用。
  3. 项目:当你有少量 npm 软件包且它们不在同一极狐GitLab群组中时使用。

如果你计划从 项目群组 安装软件包,则不必遵守命名约定。

如果你计划从 实例 安装软件包,则必须使用作用域来命名你的软件包。作用域软件包以 @ 开头,格式为 @owner/package-name。你可以在 .npmrc 文件中设置软件包的作用域,并在 package.json 中使用 publishConfig 选项。

  • 用于 @scope 的值是托管软件包的项目的根,而不是软件包本身的源代码的根。作用域应为小写。
  • 软件包名称可以是你想要的任何名称。
项目 URL软件包仓库位于作用域完整软件包名称
https://gitlab.com/my-org/engineering-group/analyticsAnalytics@my-org@my-org/package-name

确保你的 package.json 文件中的软件包名称符合此约定:

shell
"name": "@my-org/package-name"

使用命令行发布软件包#

在你配置认证后,使用以下命令发布 NPM 软件包:

shell
npm publish

如果你使用 .npmrc 文件进行认证,请设置预期的环境变量:

shell
NPM_TOKEN=<token> npm publish

如果上传的软件包有多个 package.json 文件,则只使用第一个找到的文件,其他文件将被忽略。

使用 CI/CD 流水线发布软件包#

在使用 CI/CD 流水线发布时,你可以使用 预定义变量 ${CI_PROJECT_ID}${CI_JOB_TOKEN} 来认证你的项目的软件包仓库。极狐GitLab在执行 CI/CD 作业期间使用这些变量创建 .npmrc 文件进行认证。

在你生成 .npmrc 文件时,如果端口是默认端口,请不要在 ${CI_SERVER_HOST} 后指定端口。http URL 默认使用 80https URL 默认使用 443

在包含你的 package.json 的极狐GitLab项目中,编辑或创建 .gitlab-ci.yml 文件。例如:

yaml
1default: 2 image: node:latest 3 4stages: 5 - deploy 6 7publish-npm: 8 stage: deploy 9 script: 10 - echo "@scope:registry=https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/" > .npmrc 11 - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}" >> .npmrc 12 - npm publish

@scope 替换为正在发布的软件包的 作用域

当你的流水线中的 publish-npm 作业运行时,你的软件包将发布到软件包仓库。

安装软件包#

如果多个软件包具有相同的名称和版本,当你安装软件包时,将检索到最近发布的软件包。

你可以从极狐GitLab项目、群组或实例安装软件包:

  1. 实例:当你在不同的极狐GitLab群组或它们自己的命名空间中有许多 npm 软件包时使用。
  2. 群组:当你在同一极狐GitLab群组中的不同项目中有许多 npm 软件包时使用。
  3. 项目:当你有少量 npm 软件包且它们不在同一极狐GitLab群组中时使用。

从实例安装#

先决条件:

  1. 认证到软件包仓库

  2. 设置仓库:

    shell
    npm config set @scope:registry https://<domain_name>.com/api/v4/packages/npm/
    • @scope 替换为你要安装到的软件包的顶级群组
    • <domain_name> 替换为你的域名,例如 gitlab.com
  3. 安装软件包:

    shell
    npm install @scope/my-package

从群组安装#

History
    • 在极狐GitLab 16.0 中引入,使用名为 npm_group_level_endpoints功能标志。默认禁用。
    • 在极狐GitLab 16.1 中 GA。功能标志 npm_group_level_endpoints 被移除。
  1. 认证到软件包仓库

  2. 设置仓库:

    shell
    npm config set @scope:registry=https://<domain_name>/api/v4/groups/<group_id>/-/packages/npm/
    • @scope 替换为你要安装到的软件包的顶级群组
    • <domain_name> 替换为你的域名,例如 gitlab.com
    • <group_id> 替换为群组主页上的群组 ID。
  3. 安装软件包:

    shell
    npm install @scope/my-package

从项目安装#

  1. 认证到软件包仓库

  2. 设置仓库:

    shell
    npm config set @scope:registry=https://<domain_name>/api/v4/projects/<project_id>/packages/npm/
    • @scope 替换为你要安装到的软件包的顶级群组
    • <domain_name> 替换为你的域名,例如 gitlab.com
    • <project_id> 替换为 项目概述页面 中的项目 ID。
  3. 安装软件包:

    shell
    npm install @scope/my-package

转发软件包到 npmjs.com#

History
    • 在极狐GitLab 12.9 中引入。
    • 在极狐GitLab 17.0 中更改了所需角色,从维护者更改为所有者。

当在软件包仓库中找不到 npm 软件包时,极狐GitLab 会响应 HTTP 重定向,以便请求客户端可以重新发送请求到 npmjs.com。

管理员可以在持续集成设置中禁用此行为。

群组所有者可以在群组 软件包和仓库 设置中禁用此行为。

弃用软件包#

History
    • 在极狐GitLab 16.0 中引入。

你可以弃用一个软件包,以便在获取软件包时显示弃用警告。

先决条件:

从命令行运行:

shell
npm deprecate @scope/package "弃用消息"

CLI 还接受 @scope/package 的版本范围。例如:

shell
npm deprecate @scope/package "所有软件包版本都已弃用" npm deprecate @scope/package@1.0.1 "仅版本 1.0.1 已弃用" npm deprecate @scope/package@"< 1.0.5" "所有软件包版本低于 1.0.5 的均已弃用"

当软件包被弃用时,其状态将更新为 deprecated

移除弃用警告#

要移除软件包的弃用警告,请为消息指定 ""(空字符串)。例如:

shell
npm deprecate @scope/package ""

当软件包的弃用警告被移除时,其状态将更新为 default

有用的提示#

从其他组织安装 npm 软件包#

你可以将软件包请求路由到极狐GitLab以外的组织和用户。

为此,请在你的 .npmrc 文件中添加行。将 @my-other-org 替换为拥有你的项目存储库的命名空间或群组,并使用你组织的 URL。名称区分大小写,必须与你的群组或命名空间的名称完全匹配。

shell
@scope:registry=https://my_domain_name.com/api/v4/packages/npm/ @my-other-org:registry=https://my_domain_name.example.com/api/v4/packages/npm/

npm 元数据#

极狐GitLab软件包仓库向 npm 客户端公开以下属性。

  • name
  • versions
    • name
    • version
    • deprecated
    • dependencies
    • devDependencies
    • bundleDependencies
    • peerDependencies
    • bin
    • directories
    • dist
    • engines
    • _hasShrinkwrap
    • hasInstallScript: 如果此版本有安装脚本,则为 true

添加 npm 分发标签#

你可以为新发布的软件包添加分发标签。标签是可选的,并且一次只能分配给一个软件包。

当你发布没有标签的软件包时,默认会添加 latest 标签。当你安装软件包而不指定标签或版本时,会使用 latest 标签。

支持的 dist-tag 命令的示例:

shell
npm publish @scope/package --tag # 发布带有新标签的软件包 npm dist-tag add @scope/package@version my-tag # 为现有软件包添加标签 npm dist-tag ls @scope/package # 列出软件包下的所有标签 npm dist-tag rm @scope/package@version my-tag # 从软件包中删除标签 npm install @scope/package@my-tag # 安装特定标签

从 CI/CD#

History
    • 在极狐GitLab 15.10 中引入。

你可以使用 CI_JOB_TOKEN部署令牌 在极狐GitLab CI/CD 作业中运行 npm dist-tag 命令。

先决条件:

  • 你的 npm 版本为 6.9.1 或更高版本。在早期版本中,由于 npm 6.9.0 中的 bug,删除分发标签会失败。

例如:

yaml
npm-deploy-job: script: - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">.npmrc - npm dist-tag add @scope/package@version my-tag

审核 npm 软件包#

极狐GitLab支持 npm audit 命令,允许你检查你的软件包是否存在已知的漏洞。

使用 npm audit#

先决条件:

要运行安全审核,你可以运行以下命令:

shell
npm audit --registry=https://gitlab.example.com/api/v4/packages/npm/

或者,如果你已经设置了仓库配置:

shell
npm audit

npm audit 命令会检查你的依赖项中的已知漏洞并提供报告。

npm audit 工作流#

当你针对极狐GitLab软件包仓库运行 npm audit 时,会发生以下两种情况之一:

  1. 如果启用了软件包转发(默认),极狐GitLab会将审核请求转发到 npmjs.com 以检索公共和私有软件包的漏洞信息。
  2. 如果禁用了软件包转发,极狐GitLab 会返回一个空的结果集。极狐GitLab 不会独立扫描软件包以查找漏洞。

要了解有关软件包转发设置的更多信息,请参阅软件包转发到 npmjs.com

重要的安全注意事项#

如果你没有指定极狐GitLab作为你的软件包仓库(无论是使用 --registry 标志还是通过在 .npmrc 文件中将其设置为默认仓库),审核请求将发送到公共 npm 仓库。

在这种情况下,请求体包含有关你项目中所有软件包的信息,包括你的私有极狐GitLab软件包。

为了确保你的私有软件包信息保留在极狐GitLab中,请在运行 npm audit 命令时始终确保指定极狐GitLab仓库。

限制#

  • 审核结果依赖于启用了软件包转发。如果管理员或群组所有者禁用了转发,npm audit 不会返回漏洞信息。
  • 审核请求包含关于你项目中所有软件包的信息,包括私有软件包。

支持的 CLI 命令#

极狐GitLab npm 存储库支持 npm CLI (npm) 和 yarn CLI (yarn) 的以下命令:

  • npm install: 安装 npm 软件包。
  • npm publish: 将 npm 软件包发布到仓库。
  • npm dist-tag add: 为 npm 软件包添加分发标签。
  • npm dist-tag ls: 列出软件包的分发标签。
  • npm dist-tag rm: 删除分发标签。
  • npm ci: 直接从你的 package-lock.json 文件安装 npm 软件包。
  • npm view: 显示软件包元数据。
  • npm pack: 从软件包创建一个 tarball。
  • npm deprecate: 弃用软件包的某个版本。
  • npm audit: 检查你的项目依赖项中的漏洞。

故障排除#

npm 日志不正确显示#

你可能会遇到一个错误,提示:

shell
npm ERR! A complete log of this run can be found in: .npm/_logs/<date>-debug-0

如果日志没有出现在 .npm/_logs/ 目录中,你可以将日志复制到你的根目录并在那里查看:

yaml
1 script: 2 - npm install --loglevel verbose 3 - cp -r /root/.npm/_logs/ . 4 artifacts: 5 paths: 6 - './_logs'

npm 日志作为产物复制到 /root/.npm/_logs/

npm installyarn 出现 404 Not Found 错误#

使用 CI_JOB_TOKEN 安装具有其他项目依赖项的 npm 软件包会导致 404 Not Found 错误。你需要使用具有对软件包及其所有依赖项访问权限的令牌进行认证。

如果软件包及其依赖项位于同一群组但位于不同项目中,你可以使用 群组部署令牌

toml
//gitlab.example.com/api/v4/packages/npm/:_authToken=<group-token> @group-scope:registry=https://gitlab.example.com/api/v4/packages/npm/

如果软件包及其依赖项跨多个群组分布,你可以使用 个人访问令牌 来自具有对所有群组或单个项目访问权限的用户:

toml
//gitlab.example.com/api/v4/packages/npm/:_authToken=<personal-access-token> @group-1:registry=https://gitlab.example.com/api/v4/packages/npm/ @group-2:registry=https://gitlab.example.com/api/v4/packages/npm/

个人访问令牌必须小心对待。阅读我们的令牌安全注意事项,了解管理个人访问令牌的指南(例如设置短期过期和使用最小作用域)。

npm publish 目标为默认 npm 仓库 (registry.npmjs.org)#

确保你的软件包作用域在 package.json.npmrc 文件中一致设置。

例如,如果你的极狐GitLab项目名称是 @scope/my-package,那么你的 package.json 文件应如下所示:

json
{ "name": "@scope/my-package" }

.npmrc 文件应如下所示:

shell
@scope:registry=https://your_domain_name/api/v4/projects/your_project_id/packages/npm/ //your_domain_name/api/v4/projects/your_project_id/packages/npm/:_authToken="${NPM_TOKEN}"

npm install 返回 npm ERR! 403 Forbidden#

如果你遇到此错误,请确保:

  • 你的项目设置中启用了软件包仓库。虽然软件包仓库默认启用,但可以禁用它。
  • 你的令牌没有过期并具有适当的权限。
  • 在给定的作用域内不存在具有相同名称或版本的软件包。
  • 作用域软件包的 URL 包含尾随斜杠:
    • 正确://gitlab.example.com/api/v4/packages/npm/
    • 不正确://gitlab.example.com/api/v4/packages/npm

npm publish 返回 npm ERR! 400 Bad Request#

如果你遇到此错误,可能是由以下问题之一导致的。

软件包名称不符合命名约定#

你的软件包名称可能不符合 @scope/package-name 软件包命名约定

确保名称完全符合约定,包括大小写。然后尝试重新发布。

软件包已存在#

你的软件包已经发布到同一根命名空间中的另一个项目,因此不能使用相同的名称再次发布。

即使之前发布的软件包仅共享相同的名称而不是版本,这也是如此。

软件包 JSON 文件太大#

确保你的 package.json 文件不超过 20,000 个字符。