如何把 npm 包发布到 GitLab

286 阅读4分钟

如何把 npm 包发布到 GitLab

当有需要把 npm 包私有化时,可以选择用私有 GitLab 作为 npm registry

参考


本文创作环境:

  • Node.js: v20.14
  • NPM: v10.7
  • GitLab: v16

步骤一:创建 GitLab 项目和包的身份令牌

  1. 有一个私有 gitlab 仓库
  2. 建一个分组,下称“MyGroup”
  3. 建一个源码仓库,下称“MyRepo”,要发布的包下称“MyPack”
  4. 创建身份令牌(deploy token),用来发布或安装包

创建 deploy tokens

token 的创建有不同的级别,比如项目级、分组级、实例级,这里创建的 token 是分组级别的,位置:

gitlab / MyGroup / Settings / Repository / Deploy tokens

若想在项目级别下创建,则前部分的路径改为 gitlab / MyGroup / MyRepo 去找就行了。

点击创建按钮,勾选相关的权限。生成 token 后马上复制保存起来,此值后面不再出现。根据包维护者和使用者等不同身份,自行创建不同权限的 token 即可。

其实用 ... / Settings / Access Tokens 创建应该也行,我也没去研究有什么区别。

到此,已经拥有 MyPack 的发布或安装令牌了。


步骤二:用命令行发布 npm 包到 gitlab

准备一个 npm 包

npm 包组成的基础就不展开说了,比如版本号什么的,提一下注意点:

  • package.jsonname@scope/pack-name 的格式,即要带 scope
  • package.jsonprivate 不能为 false,否则发布不了

身份验证和镜像源

因为是私有包,我们需要一个地方去配置这个包的发布地址和相关令牌。所以需要配置 .npmrc,它是 npm 的配置文件

.npmrc 的文件位置

.npmrc 有几个级别,项目级 > 用户级 > 全局 > 内置,自行决定在哪个级别下配置 .npmrc

比如在代码项目下修改 .npmrc

npm config set key=value --location project

编辑 .npmrc

.npmrc 里设置相关信息:

# 指定 @scope 下的包,其发布或安装的镜像源
${@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}"

字段解析:

  • @scope:这个包的 scope
  • your_domain_name:私有 GitLab 域名
  • your_project_id:要发布的项目 ID,在 MyRepo 的设置里能看到
  • NPM_TOKEN:之前弄的身份令牌

为了让包的信息更清晰,在 package.json 里修改 publishConfig 字段,用来说明发布到哪里。

"publishConfig": {
    "@scope:registry": "https://${your_domain_name}/api/v4/projects/${your_project_id}/packages/npm/"
 }

现在,可以发布包了:

  • git bash
NPM_TOKEN=your_token npm publish
  • powershell
$env:NPM_TOKEN=your_token
npm publish

发布成功后,在 gitlab / MyGroup / Deploy / Package Registry 能看到这个私有包了。除了分组里能看见,在对应的项目里也能看见。

your_project_id 的额外使用方法

另外,若是以 @scope/pack-name 的形式,your_project_id 我们会下意识填写包对应的源码项目 ID,但其实包的发布地方和源码项目不要求一一对应。

我们可以把包都推送到 gitlab 的一个根项目下,比如分组的 gitlab-profile 项目,这样可以方便一次性配置所有包的 _authToken


步骤三:安装这个私有包

身份验证

使用这个包的项目,需要去配置这个私有包的安装地址和令牌,也是在 .npmrc 里配,请自行决定用哪个层级的 .npmrc,下面用了全局配置来举例。

提示:你可能需要重新创建一个仅有使用权限的令牌。

和发布不同,安装者要设置的镜像源地址和身份验证,分 3 个级别,分别对应在哪个级别下创建的这个令牌,参考官网文档

三个令牌级别:

  • GitLab 实例级别 (instance level)
# 安装地址
npm config set @scope:registry https://your_domain_name.com/api/v4/packages/npm/
# 身份验证
npm config set -- //your_domain_name/api/v4/packages/npm/:_authToken=your_token
  • GitLab 分组级别 (group level)
npm config set @scope:registry=https://your_domain_name/api/v4/groups/your_group_id/-/packages/npm/
npm config set -- //your_domain_name/api/v4/groups/your_group_id/-/packages/npm/:_authToken=your_token
  • GitLab 项目级别 (project level)
npm config set @scope:registry=https://your_domain_name/api/v4/projects/your_project_id/packages/npm/
npm config set -- //your_domain_name/api/v4/projects/your_project_id/packages/npm/:_authToken=your_token

配置 .npmrc 后,像往常一样 npm install 即可。


遇到的问题

使用 group 的 authToken 无法使用 npm alias 安装私有包

希望使用别名安装一个私有包:

npm i element@npm:@myScope/element@^10.0.0

.npmrc 配置了分组权限 //xxxx.com/api/v4/groups/分组ID/-/packages/npm/:_authToken=xxxx,但安装报错 404,不用别名安装则安装成功,未找到具体原因。

猜测是用别名安装时,会直接安装项目级别下的 .tgz 资源文件,但 npmrc 配了分组级别的令牌,所以无法找到资源。

目前解决方法是在 .npmrc 里也加一个项目级别的权限。