以前、Tailwind CSSを使ったコンポーネントの設定を複数のプロジェクトで使いまわす方法を調べた。
GitリポジトリとしてGitLab.comを使っており、GitLabのパッケージレジストリにnpmパッケージを公開することで、公開範囲を絞ることができるため、その方法をメモ。
環境
Node.js v16.15.1, npm v8.11.0, Yarn v1.22.19。
OSはWindows 10 Pro 64bit 21H2、コマンドはGit 2.35.1.windows.2のGit Bashから実行して確認。
GitLabの設定
GitLab上でプライベートなプロジェクトを作成しておく。
パッケージレジストリの種類として、プロジェクトレベルとインスタンスレベルがある。今回はインスタンスレベルで設定する。
インスタンスレベルの場合、npmパッケージはスコープ付きにする必要がある。Gitプロジェクトが属するグループ名の先頭に @
を付与したものが、npmパッケージのスコープ名となる。
なお、実際のソースコードが書かれたGitプロジェクトと、npmパッケージを公開するGitプロジェクトは同じである必要はない。
パッケージ公開するNode.jsプロジェクトの設定
アクセストークンの発行
GitLab CI/CDによるパイプライン内ではなく、手動で実行する場合、パッケージレジストリとするGitプロジェクトにアクセス可能な、アクセストークンを発行する。アクセストークンのスコープは、 api
のみでいい。
発行したトークンは、 .bashrc
などで export NPM_TOKEN=...
しておく。
package.json の変更
package.json
の name
を、 <スコープ名>/任意のパッケージ名
に変更する。
GitLabのグループ名が my-org
、パッケージ名を components
とする場合、 @my-org/components
。 *1
また、 private
が true
であれば false
にしておく。
.npmrc の変更
.npmrc
に、以下の記述を追加。公開するGitLabプロジェクトのプロジェクトIDが必要となる。
<スコープ名>:registry=https://<GitLabドメイン>/api/v4/projects/<プロジェクトID>/packages/npm/ //<GitLabドメイン>/api/v4/projects/<プロジェクトID>/packages/npm/:_authToken=${NPM_TOKEN}
${NPM_TOKEN}
には環境変数が設定される。GitLabドメインは、GitLab.comを使用している場合は gitlab.com
、オンプレミス環境であればそのドメインを設定する。
例として、GitLab.com上のGitプロジェクトで、グループ名が my-org
, プロジェクトIDが 12345678
の場合、以下のようになる。
@my-org:registry=https://gitlab.com/api/v4/projects/12345678/packages/npm/ //gitlab.com/api/v4/projects/12345678/packages/npm/:_authToken=${NPM_TOKEN}
GitLab CI/CDのパイプライン経由で公開する場合
GitLab CI/CDのパイプライン経由でパッケージ公開を行う場合、CI/CD時の環境変数を利用するよう書き換えることも可能。
@my-org:registry=https://gitlab.com/api/v4/projects/12345678/packages/npm/ //gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}
レジストリURLは、 @${CI_PROJECT_NAMESPACE}:registry=https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/
のようにも書き換えられそうだが、ローカルでうっかり npm publish
したときに www.npmjs.com
に向きそうなので、固定値で設定している。
公開処理の実行
npm publish --dry-run
し、 Publishing to ...
で表示されるURLが、指定したレジストリURL(この例では https://gitlab.com/api/v4/projects/12345678/packages/npm/
)となっていれば正しく設定できている。
npm publish
を実行したら、ブラウザで公開先のGitLabプロジェクトのページを開き、左フレームの「パッケージとレジストリ」>「パッケージレジストリ」を開く。
指定したパッケージ名およびバージョンで、npmパッケージが登録されていれば成功。
パッケージを利用するNode.jsプロジェクトの設定
アクセストークンの発行
パッケージレジストリとするGitプロジェクトにアクセス可能な、アクセストークンを発行する。アクセストークンのスコープは、 read_api
のみでいい。
また、スコープ api
は read_api
を含むので、パッケージ公開するNode.jsプロジェクトの設定を行っているのであれば流用可能。
.npmrc の変更
.npmrc
に、以下の記述を追加。公開側との違いとして、 /project/<プロジェクトID>
が不要となっている。
<スコープ名>:registry=https://<GitLabドメイン>/api/v4/packages/npm/ //gitlab.com/api/v4/packages/npm/:_authToken=${NPM_TOKEN}
例として、GitLab.com上のGitプロジェクトで、グループ名が my-org
の場合、以下のようになる。
@my-org:registry=https://gitlab.com/api/v4/packages/npm/ //gitlab.com/api/v4/packages/npm/:_authToken=${NPM_TOKEN}
この設定が正しく行われていれば、普通に npm install
できる。
Yarnを用いる場合
それぞれ npm publish
および npm install
で動作確認したが、プロジェクトのパッケージマネージャーとしてはYarn Classicを使っている。
それぞれ yarn publish
とyarn add
に置き換えられないか確認した。
yarn publishによるパッケージ公開
結論から言うと、まったく使い物にならなかったので、 npm publish
を使い続けることとした。
yarn publish
はデフォルトでは対話型だが、 yarn publish -non-interactive
で非対話型で実行できるものの、いろいろと問題があった。
- パッケージに含めるファイルを調整したときに、確認のため
npm pack --dry-run
を使うが、npm pack
に該当するコマンドがYarnにない- issueはあるが放置
- Yarn v2以降であれば追加された模様
package.json
のfiles
で指定していないファイルがパッケージに含まれる
yarn publishの改善のissueもあるが、改善されそうもないので、 npm publish
を使う。
yarn addによるパッケージ追加
yarn add
を実行すると以下のエラーが発生する。
error An unexpected error occurred: "https://
ドメイン>/api/v4/projects/<プロジェクトID>/packages/npm/<スコープ名>/<パッケージ名>/-/<スコープ名>/<パッケージ名>-<バージョン>.tgz: Request failed \"404 Not Found\"".
同じ問題の質問が、GitLabフォーラムにあった。
コメントにあるように、 .npmrc
に //<GitLabドメイン>/api/v4/projects/:_authToken=${NPM_TOKEN}
を追加すると成功するようになった。
先の例に追加すると、以下のようになる。
@my-org:registry=https://gitlab.com/api/v4/packages/npm/ //gitlab.com/api/v4/packages/npm/:_authToken=${NPM_TOKEN} //gitlab.com/api/v4/projects/:_authToken=${NPM_TOKEN}
振り返り
基本的には公式ドキュメント通りに進めるだけだったが、Yarnを使う場合にはもろもろ手直しが必要だった。
特にpublishの挙動の違いにはまいった、なぜうまく動かないのかもよくわからない。npm用の設定ファイルが読み込まれていないのか?
ただ、掘り下げるのも時間の無駄なので、調査はしていない。
あと、そろそろYarnもmodernに乗り換えないとかなぁ。
*1:グループ名は example にしようと思ったが、GitLab.com上に存在していた