- 构建 npm 包
- 将 GitLab 端点用于 npm 包
- 向软件包库进行身份验证
- 与私有库工作
- 包命名约定
- 限制
- 发布一个 npm 包
- 使用 CI/CD 发布 npm 包
- 使用 Yarn 2 配置 GitLab npm 库
- 发布具有相同名称或版本的包
package.json
限制- 安装软件包
- 添加 npm 分发标签
- 故障排查
- 支持的 CLI 命令
软件包库中的 npm 包
在项目的软件宝库中发布 npm 包。然后在需要将它们用作依赖项时安装它们。
仅支持 scoped 包。
.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
创建项目
创建项目:
- 创建一个空目录。
-
进入目录并初始化一个空包:
npm init
或者,如果您使用的是 Yarn:
yarn init
- 输入问题的答案。确保 包名称 遵循命名约定并且范围限定为库所在的项目或群组。
一个 package.json
文件被创建。
将 GitLab 端点用于 npm 包
要将 GitLab 端点用于 npm 包,请选择一个选项:
- 项目级别:当您的 npm 包很少并且它们不在同一个 GitLab 组中时使用。包命名约定在此级别未强制执行。相反,您应该为您的包使用 scope。当您使用 scope 时,库 URL 仅为该 scope 更新。
- 实例级别:当您在不同的 GitLab 群组或它们自己的命名空间中有许多 npm 包时使用。请务必遵守包命名约定。
某些功能,例如发布包仅在项目级端点上可用。
向软件包库进行身份验证
当项目是私有的时,您必须通过软件包库进行身份验证。公开项目不需要身份验证。
要进行身份验证,请使用以下方法之一:
-
个人访问令牌(双重身份验证(2FA)所需),范围设置为
api
。 - 部署令牌,范围设置为
read_package_registry
、write_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 包。
实例级 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 包了。
使用 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 项目中使用 npm
或 yarn
命令安装。您可以安装项目或实例范围内的包。
如果多个包具有相同的名称和版本,则在安装包时,将检索最近发布的包。
-
设置 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。
- 用您的 scope 替换
-
确保已配置身份验证。
-
要在项目中安装包,请运行:
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
:更新您的依赖项。