软件包库中的 npm 包

在项目的软件宝库中发布 npm 包。然后在需要将它们用作依赖项时安装它们。

仅支持 scoped 包。

caution永远不要直接在 .npmrc 文件或任何其他可以提交到仓库的文件中硬编码 GitLab 令牌(或任何令牌)。

构建 npm 包

本节介绍如何安装 npm 或 Yarn 并为您的 JavaScript 项目构建包。

如果您已经使用 npm 并且知道如何构建自己的包,请转到下一节

安装 npm

按照 npmjs.com 上的说明,在本地开发环境中安装 Node.js 和 npm。

安装完成后,通过运行以下命令验证您是否可以在终端中使用 npm:

npm --version

npm 版本显示在输出中:

6.10.3

安装 Yarn

作为 npm 的替代方案,您可以按照 classic.yarnpkg.com 上的说明在本地环境中安装 Yarn。

安装完成后,通过运行以下命令验证您可以在终端中使用 Yarn:

yarn --version

Yarn 版本显示在输出中:

1.19.1

创建项目

创建项目:

  1. 创建一个空目录。
  2. 进入目录并初始化一个空包:

    npm init
    

    或者,如果您使用的是 Yarn:

    yarn init
    
  3. 输入问题的答案。确保 包名称 遵循命名约定并且范围限定为库所在的项目或群组。

一个 package.json 文件被创建。

将 GitLab 端点用于 npm 包

要将 GitLab 端点用于 npm 包,请选择一个选项:

  • 项目级别:当您的 npm 包很少并且它们不在同一个 GitLab 组中时使用。包命名约定在此级别未强制执行。相反,您应该为您的包使用 scope。当您使用 scope 时,库 URL 仅为该 scope 更新
  • 实例级别:当您在不同的 GitLab 群组或它们自己的命名空间中有许多 npm 包时使用。请务必遵守包命名约定

某些功能,例如发布包仅在项目级端点上可用。

向软件包库进行身份验证

当项目是私有的时,您必须通过软件包库进行身份验证。公开项目不需要身份验证。

要进行身份验证,请使用以下方法之一:

  • 个人访问令牌(双重身份验证(2FA)所需),范围设置为 api
  • 部署令牌,范围设置为 read_package_registrywrite_package_registry,或两者均有。
  • 不推荐,但您可以使用 OAuth 令牌。标准 OAuth 令牌无法向 GitLab npm Registry 进行身份验证。您必须使用带有 OAuth 标头的个人访问令牌。
  • CI 作业令牌
  • 您的 npm 包名称必须采用 @scope/package-name 格式。它必须完全匹配,包括大小写。

使用个人访问令牌或部署令牌进行身份验证

要使用软件包库进行身份验证,您需要一个个人访问令牌或部署令牌。

项目级别 npm 端点

要使用项目级别 npm 端点,请设置您的 npm 配置:

# Set URL for your scoped packages.
# For example package with name `@foo/bar` will use this URL for download
npm config set @foo:registry https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/

# Add the token for the scoped packages URL. Replace <your_project_id>
# with the project where your package is located.
npm config set -- '//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken' "<your_token>"
  • <your_project_id> 是您的项目 ID,可在项目主页上找到。
  • <your_token> 是您的个人访问令牌或部署令牌。
  • 用您的域名替换 gitlab.example.com

您现在应该能够在您的项目中发布和安装 npm 包。

如果遇到 Yarn 的错误,请查看故障排查

实例级 npm 端点

要使用实例级别 npm 端点,请设置您的 npm 配置:

# Set URL for your scoped packages.
# For example package with name `@foo/bar` will use this URL for download
npm config set @foo:registry https://gitlab.example.com/api/v4/packages/npm/

# Add the token for the scoped packages URL. This will allow you to download
# `@foo/` packages from private projects.
npm config set -- '//gitlab.example.com/api/v4/packages/npm/:_authToken' "<your_token>"
  • <your_token> 是您的个人访问令牌或部署令牌。
  • 用您的域名替换 gitlab.example.com

您现在应该可以在您的项目中安装 npm 包了。

如果您在使用 Yarn 时遇到错误,请查看故障排查步骤

使用 CI 作业令牌进行身份验证

如果您将 npm 与 GitLab CI/CD 一起使用,则可以使用 CI 作业令牌代替个人访问令牌或部署令牌。 令牌继承生成流水线的用户的权限。

项目级 npm 端点

要使用项目级别 npm 端点,请在您的 .npmrc 文件中添加相应的部分:

@foo:registry=https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/
//gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}

实例级 npm 端点

要使用实例级别 npm 端点,请将相应的部分添加到您的 .npmrc 文件中:

@foo:registry=https://gitlab.example.com/api/v4/packages/npm/
//gitlab.example.com/api/v4/packages/npm/:_authToken=${CI_JOB_TOKEN}

使用变量来避免对身份验证令牌值进行硬编码

为了避免对 authToken 值进行硬编码,您可以在它的位置使用一个变量:

npm config set -- '//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken' "${NPM_TOKEN}"
npm config set -- '//gitlab.example.com/api/v4/packages/npm/:_authToken' "${NPM_TOKEN}"

然后,您可以在本地或使用 GitLab CI/CD 运行 npm publish

  • 本地: 发布前导出NPM_TOKEN

    NPM_TOKEN=<your_token> npm publish
    
  • GitLab CI/CD: 在项目的 设置 > CI/CD > 变量 下设置一个 NPM_TOKEN CI/CD 变量

与私有库工作

使用私有库时,您可能需要配置其他设置以确保安全的通信通道:

# Force npm to always require authentication when accessing the registry, even for GET requests.
npm config set always-auth true

包命名约定

当您使用实例级端点时,只有名称为 @scope/package-name 格式的包可用。

  • @scope 是 GitLab 项目的根命名空间。为了遵循 npm 的约定,它应该是小写的。但是,GitLab 软件包库允许使用大写字母。在 13.10 版本之前,@scope 必须是 GitLab 项目根命名空间的区分大小写的匹配项。这是有问题的,因为 npm 公共库不允许大写字母。13.10 版本放宽了这一要求,并将 GitLab @scope 中的大写转换为 npm 的小写。例如,GitLab 中的包 @MyScope/package-name 变为 npm 的 @myscope/package-name
  • package-name 可以是任何您想要的。

例如,如果您的项目是 https://gitlab.example.com/my-org/engineering-group/team-amazing/analytics,则根命名空间是 my-org。当您发布一个包时,它必须以 my-org 作为范围。

项目 是否支持
my-org/bar @my-org/bar Yes
my-org/bar/baz @my-org/baz Yes
My-Org/Bar/baz @my-org/Baz Yes
My-Org/Bar/baz @My-Org/Baz Yes
my-org/bar/buz @my-org/anything Yes
gitlab-org/gitlab @gitlab-org/gitlab Yes
gitlab-org/gitlab @foo/bar No

在 GitLab 中,此正则表达式验证来自所有包管理器的所有包名称:

/\A\@?(([\w\-\.\+]*)\/)*([\w\-\.]+)@?(([\w\-\.\+]*)\/)*([\w\-\.]*)\z/

该正则表达式允许使用 npm 允许的几乎所有字符,但有一些例外(例如,不允许使用 ~)。

正则表达式还允许使用大写字母,而 npm 则不允许。

限制

当您更新用户或群组的路径,或转移子组或项目时,您必须先删除所有 npm 包。您无法使用 npm 包更新项目的根命名空间。确保更新您的 .npmrc 文件以遵循命名约定,并在必要时运行 npm publish

发布一个 npm 包

先决条件:

  • 身份验证到软件包库。
  • 设置项目级 npm 端点。

要将 npm 包上传到您的项目,请运行以下命令:

npm publish

要查看包,请转到您项目的 软件包和镜像库

您还可以在 package.json 中为您的项目定义 "publishConfig"。例如:

{
"publishConfig": { "@foo:registry":" https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/" }
}

这会强制包仅发布到指定的库。

如果您尝试在给定范围内发布一个名称已经存在的包,您会收到 403 Forbidden! 错误。

使用 CI/CD 发布 npm 包

先决条件:

  • 身份验证到软件包库。
  • 设置项目级 npm 端点。
  • 您的 npm 包名称必须采用 @scope/package-name 格式。它必须完全匹配,包括大小写。这与 npm 命名约定不同,但它需要与 GitLab 软件包库一起使用。

要在 GitLab CI/CD 中使用 npm 命令,您可以在命令中使用 CI_JOB_TOKEN 代替个人访问令牌或部署令牌。

用于发布 npm 包的示例 .gitlab-ci.yml 文件:

image: node:latest

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">.npmrc
    - npm publish
  environment: production

使用 Yarn 2 配置 GitLab npm 库

您可以按照 Yarn 文档开始使用 Yarn 2。

要使用项目级 npm 端点发布和安装,请在 .yarnrc.yml 中设置以下配置:

npmScopes:
  foo:
    npmRegistryServer: "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/"
    npmPublishRegistry: "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/"

npmRegistries:
  //gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<your_token>"

对于实例级 npm 端点,请使用 .yarnrc.yml 中的 Yarn 2 配置:

npmScopes:
  foo:
    npmRegistryServer: "https://gitlab.example.com/api/v4/packages/npm/"

npmRegistries:
  //gitlab.example.com/api/v4/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<your_token>"

在这个配置中:

  • <your_token> 替换为您的个人访问令牌或部署令牌。
  • <your_project_id> 替换为您的项目 ID,您可以在项目主页上找到该 ID。
  • 用您的域名替换 gitlab.example.com
  • 您的范围是 foo,没有 @

发布具有相同名称或版本的包

如果已存在具有相同名称和版本的包,则无法发布包。 您必须先删除现有的包。

此规则具有不同的影响,具体取决于包名称:

  • 对于遵循命名约定的包,您不能将具有重复名称和版本的包发布到根命名空间。
  • 对于不遵循命名约定的包,您不能将具有重复名称和版本的包发布到您上传的目标项目。

这与 npmjs.org 的行为一致。 但是,npmjs.org 不允许您多次发布相同的版本,即使它已被删除。

package.json 限制

如果包的 package.json 文件超过 20,000 个字符,则无法发布包。

安装软件包

npm 包通常通过在 JavaScript 项目中使用 npmyarn 命令安装。您可以安装项目或实例范围内的包。

如果多个包具有相同的名称和版本,则在安装包时,将检索最近发布的包。

  1. 设置 scoped 包的 URL。

    对于实例级端点,运行:

    npm config set @foo:registry https://gitlab.example.com/api/v4/packages/npm/
    
    • 用您的 scope 替换 @foo
    • gitlab.example.com 替换为您的域名。

    对于项目级端点,运行:

    npm config set @foo:registry https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/
    
    • 用您的 scope 替换 @foo
    • gitlab.example.com 替换为您的域名。
    • <your_project_id> 替换为您在项目主页上的项目 ID。
  2. 确保已配置身份验证。

  3. 要在项目中安装包,请运行:

    npm install @my-scope/my-package
    

    或者,如果您使用的是 Yarn:

    yarn add @my-scope/my-package
    

在 12.9 及更高版本中,当 Package Registry 中找不到 npm 包时,将请求转发到 npmjs.com

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

安装来自其他组织的 npm 包

您可以将包请求路由到 GitLab 之外的组织和用户。

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

使用环境变量来设置您的令牌:export MY_TOKEN="<your token>"

@foo:registry=https://gitlab.example.com/api/v4/packages/npm/
//gitlab.example.com/api/v4/packages/npm/:_authToken=${MY_TOKEN}
//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken=${MY_TOKEN}

@my-other-org:registry=https://gitlab.example.com/api/v4/packages/npm/
//gitlab.example.com/api/v4/packages/npm/:_authToken=${MY_TOKEN}
//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken=${MY_TOKEN}

npm 元数据

GitLab 软件包库向 npm 客户端公开以下属性。类似于缩写元数据格式

  • name
  • versions
    • name
    • version
    • deprecated
    • dependencies
    • devDependencies
    • bundleDependencies
    • peerDependencies
    • bin
    • directories
    • dist
    • engines
    • _hasShrinkwrap

添加 npm 分发标签

您可以将 分发标签 添加到新发布的包中。 标签是可选的,一次只能分配给一个包。

当您发布一个没有标签的包时,默认会添加 latest 标签。 当您在未指定标签或版本的情况下安装软件包时,将使用 latest 标签。

支持的 dist-tag 命令示例:

npm publish @scope/package --tag               # Publish a package with new tag
npm dist-tag add @scope/package@version my-tag # Add a tag to an existing package
npm dist-tag ls @scope/package                 # List all tags under the package
npm dist-tag rm @scope/package@version my-tag  # Delete a tag from the package
npm install @scope/package@my-tag              # Install a specific tag

您不能使用 CI_JOB_TOKEN 或通过 npm dist-tag 命令部署令牌。

由于 npm 6.9.0 中的错误,删除分发标记失败。确保您的 npm 版本为 6.9.1 或更高版本。

故障排查

在对 npm 问题进行故障排查时,首先运行带有 --verbose 标志的相同命令,以确认您正在点击哪个库。

为了提高性能,npm 缓存与包相关的文件。请注意,npm 不会自行删除数据。缓存会随着新软件包的安装而增长。如果遇到问题,请使用以下命令清除缓存:

npm cache clean --force

使用 npm 库的软件包库运行 Yarn 时出错

如果您在 npm 库中使用 Yarn,您可能会收到如下错误消息:

yarn install v1.15.2
warning package.json: No license field
info No lockfile found.
warning XXX: No license field
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error An unexpected error occurred: "https://gitlab.example.com/api/v4/projects/XXX/packages/npm/XXX/XXX/-/XXX/XXX-X.X.X.tgz: Request failed \"404 Not Found\"".
info If you think this is a bug, please open a bug report with the information provided in "/Users/XXX/gitlab-migration/module-util/yarn-error.log".
info Visit https://classic.yarnpkg.com/en/docs/cli/install for documentation about this command

在这种情况下,尝试将其添加到您的 .npmrc 文件中(并将 <your_token> 替换为您的个人访问令牌或部署令牌):

//gitlab.example.com/api/v4/projects/:_authToken=<your_token>

在动态设置 auth-token 时,您还可以使用 yarn config 代替 npm config

yarn config set '//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken' "<your_token>"
yarn config set '//gitlab.example.com/api/v4/packages/npm/:_authToken' "<your_token>"

npm publish 目标是默认的 npm 库(registry.npmjs.org

确保您的包 scope 在您的 package.json.npmrc 文件中设置一致。

例如,如果您在极狐GitLab 中的项目名称是 foo/my-package,那么您的 package.json 文件应该是这样的:

{
  "name": "@foo/my-package",
  "version": "1.0.0",
  "description": "Example package for GitLab npm registry",
}

.npmrc 文件应该如下所示:

//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken=<your_token>
//gitlab.example.com/api/v4/packages/npm/:_authToken=<your_token>
@foo:registry=https://gitlab.example.com/api/v4/packages/npm/

npm install 返回 Error: Failed to replace env in config: ${npm_TOKEN}

除非您的项目是私有的,否则您不需要令牌来运行 npm install。令牌只在发布时必需。如果 .npmrc 文件是通过引用 $npm_TOKEN 检入的,您可以删除它。如果您希望保留引用,则必须在运行 npm install 之前设置一个值,或者使用 GitLab CI/CD 变量 设置该值:

NPM_TOKEN=<your_token> npm install

npm install 返回 npm ERR! 403 Forbidden

如果您收到此错误,请确保:

  • 在您的项目设置中启用了软件包库。尽管默认情况下启用软件包库,但可以禁用它。
  • 您的令牌未过期并且具有适当的权限。
  • 给定范围内不存在具有相同名称或版本的包。
  • scoped 包 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 个字符

npm publish 返回 npm ERR! 500 Internal Server Error - PUT

日志中的错误将显示为:

>NoMethodError - undefined method `preferred_language' for #<Rack::Response

这可能伴随着另一个错误:

>Errno::EACCES","exception.message":"Permission denied

这通常是权限问题:

  • 'packages_storage_path' 默认为 /var/opt/gitlab/gitlab-rails/shared/packages/
  • 如果使用对象存储的远端存储桶。

在后一种情况下,请确保存储桶存在并且 GitLab 对其具有写入权限。

支持的 CLI 命令

GitLab npm 仓库支持以下用于 npm CLI (npm) 和 yarn CLI (yarn) 的命令:

  • npm install:安装 npm 包。
  • npm publish:将 npm 包发布到库。
  • npm dist-tag add:将 dist-tag 添加到 npm 包。
  • npm dist-tag ls:列出包的 dist-tags。
  • npm dist-tag rm:删除一个 dist-tag。
  • npm ci:直接从你的 package-lock.json 文件安装 npm 包。
  • npm view:显示包元数据。
  • yarn add:安装一个 npm 包。
  • yarn update:更新您的依赖项。