🤫

GitLab で npm モジュールをホストする

2023/04/03に公開

はじめに

そこそこ大きな規模のプロジェクトを進めていると、よく 「このコンポーネントをリポジトリ間で共有したい!」 という状況に出くわします。
そういった時僕はよくライブラリ的な機能を持つリポジトリを作り、①サブモジュール機能を使って複数プロジェクトで共有する か、npm パッケージ化して限定公開 します。

この記事では、②の npmパッケージ化 して、GitLab を使ってプライベートな状態でホストする手順を紹介したいと思います。

ちなみに公式にもドキュメントがあるので、この記事で不足してる部分はこちらをご参照ください🙇

https://docs.gitlab.com/ee/user/packages/npm_registry/

モジュールを作成してアップロードする

まずは、モジュール自体を作って GitLab にアップロードします。
今回は Runner を使ってデプロイするので、 Runner も使えるようにしておいてください。以前関連する記事を書いたので、良ければ参照してみて下さい。

オンプレミスな GitLab を立ち上げる方法

https://qiita.com/soumi/items/baaa35b37f6c90a66c0c

GitLabRunner を追加する方法

https://zenn.dev/soumi/articles/ed23a05316cc2c

GitLab 上にグループとプロジェクトを作る

まずは、GitLab上にグループとプロジェクトを作ります。
今回は、グループ名:testプロジェクト名:moduleで作りました。また、今回はプライベートな状態でサーブする形にしたいので、アクセス範囲は public 以外(要認証)にしておきます。

ソースを配置

コードを書いていきます。
今回はサンプルという事で、入力した文字列を console に出力するだけのシンプルなコードにしていきます。

index.js
module.exports = {
  test: (message) => {
    console.log("this is test. message is " + message);
  },
};

ts で使った時に補完されるように、d.ts も書いておきます。

type.d.ts
export declare function test(message: string): void;

コードとしては以上で、あとはパッケージの情報を package.json にまとめていきます。

package.json
{
  "name": "@test/module",
  "version": "0.0.1",
  "main": "index.js",
  "typings": "type.d.ts"
}

CI を書く

パブリッシュを Runner で走らせるための CI を書いていきます。
記述内にたくさん環境変数が出てきますが、これらは全て GitLab が標準で提供している環境変数になるので、特に自分で用意するべき変数はなく、そのままデプロイできます。

.gitlab-ci.yml
image: node:latest

stages:
  - deploy

deploy:
  stage: deploy
  tags:
    - docker-runner
  script:
    - echo "registry=https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/">.npmrc
    - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">>.npmrc
    - cat .npmrc
    - npm publish
  only:
    refs:
      - master

今回はテストなので master ブランチに push されたら走るようにしていますが、運用時は release とか publish といったブランチを切って、そこに push あるいは merge されたら走るようにするといいと思います。

push

この状態で push すると CI が走ります。CI が完了すると、GitLabPackages and registries からパブリッシュされたパッケージを見る事が出来ます。

ホストされているモジュールを使用する

パッケージのホストが完了したので、それを使うサンプルを作っていきます。

プロジェクトを初期化する

まずは適当な nodejs のプロジェクトを作ります。僕はこういう時はいつも以下の手順で初期化しています。宜しければお試しください。

https://zenn.dev/soumi/articles/e6bcd79e962a4d

パッケージにアクセスするためのトークンを取得する

今回はプライベートな状態でホストされているパッケージを使う事になるので、認証が必要になります。
認証はトークンを使って行いますが、トークンを取得できるところは3つあり、権限の影響範囲が異なります。

場所 範囲
ユーザー設定 -> Access Tokens ユーザーがアクセスできるプロジェクト全て
グループ設定 -> Access Tokens そのグループ内のプロジェクト
プロジェクト設定 -> Access Tokens そのプロジェクトだけ

適切なものを選び、トークンを取得して下さい。Rolescope は、以下を参考にして設定して下さい。

https://docs.gitlab.com/ee/user/packages/npm_registry/#authentication-to-the-package-registry
https://docs.gitlab.com/ee/user/packages/package_registry/index.html#package-registry-visibility-permissions

僕の場合は、パッケージが Private だったので、RoleReporterScope は二段階認証をしている関係上 API が必要でした。

.npmrc を書く

普通に npm でインストールコマンドを叩くと公式の npm レジストリを読みに行ってしまうので、 指定したパッケージは別のレジストリを読みに行くように設定します。

プロジェクトルートに .npmrc を置き、以下のように記述します。

@test:registry=https://<URL>/api/v4/packages/npm/
//<URL>/api/v4/packages/npm/:_authToken=<TOKEN>

<URL> にはモジュールをホストしている GitLabURL<TOKEN> には前項で取得したトークンで置き換えます。

インストール

ここまで準備をしたら、他の npm パッケージと同じようにインストールできます。

yarn add @test/module

使う

他のパッケージと同じように import 可能で、使い方も同様です。

app.ts
import { test } from "@test/module";
test("hello!");
// this is test. message is hello!

おわりに

開発者が複数人いるプロジェクトは世の中にたくさんあると思うので、こういった方法も至る所で採用されているのであろうと思うのですが、自分用のメモも兼ねて今回記事にしました。

同じような事がしたい方の力になれれば幸いです。

Discussion