TSでnpmパッケージを作ってみる ~開発・運用編~

前回TSでnpmパッケージを作るにあたって、tsconfig.jsonやpackage.json、ビルド関連の設定を行なった。

あわせて読みたい
TypeScriptでnpmパッケージを作ってみる ~設定編~ 自作のnpmパッケージを作りたくて作ってみた。いや、正確には作ろうとしたものがあったのだが、途中で作るモチベーションがなくなったので作って公開まではしていない。...

これによって一通りnpmパッケージをpublishすることができるようになった。
今回は実際に中身を開発していく際のパッケージの動作確認方法だったり、運用するためのGitHub Actionsでのいい感じの設定方法とかをまとめていく。

具体的には以下のことができるようになる

・yarn linkを使って開発中のパッケージを読み込む
・PR作成時にブランチ名に応じたlabelをつけてくれるようになる
・リリース時にリリースノートのドラフトを作成してくれるようになる

目次

パッケージ開発時の動作確認

実際にパッケージの中身を開発しているとそれを読み込んだ時に正常に動作するかを確認したくなる。
その度にnpmにpublishするのはやってられないのでローカルで完結させたい。

方法としては圧縮したファイルをインストールする方法とnpm(yarn) linkでシンボリックリンクを貼る方法の2つが代表的

圧縮したファイルをインストール

これは動作確認したい内容のものを圧縮ファイルにして、それを使う側でインストールするという方法

具体的には動作確認したいものをまずビルドする。
その後npm(yarn) packというコマンドを叩くと圧縮ファイルがルートディレクトリに吐き出される。

あとは動作確認するために別の検証用プロジェクトでこの圧縮ファイルのpathに対してインストールを行う

yarn add --dev ~/project_path_to_npm_pack_file

ただこの方法だと動作確認するたびにビルドしてインストールし直してってのをやらないといけないので中々めんどい。。。
しかもインストールする側でyarnのcacheが効いてる?のか分からないがpackage.jsonのversionを変更してビルドし直さないと新しい内容が反映されてなかった

なので次に示すシンボリックリンクを貼る方法の方がおすすめ

yarn linkでシンボリックリンクを貼る

動作確認したいパッケージでyarn linkとやるとシンボリックリンクが作成される

あとは動作確認をする検証用のプロジェクトでそのパッケージをインストールする
この時指定するのはpackage.jsonに記載したnameの値

yarn link package-name

これはシンボリックリンクなので開発しているパッケージの内容と同期されている。
従って、開発中のパッケージを変更してビルドし直せばそれを読み込んでいるところでもその変更が反映される

さらに前回、ビルドの設定で開発中はwatchモードでビルドするようにしたのでコードの変更は勝手に検知されて再ビルドされる。
つまり、コードを変更しただけで読み込む側ではその変更が反映されることになるので非常に便利

ライブラリのバージョンを更新する

開発を継続して行なっていると中身を変更してnpmに再度publishする必要が出てくる

再publishする際にはpackage.jsonのversionを上げる必要がある
これはそのままコードとして修正した上でpublishしてもいいのだが、コマンドがあるのでせっかくなのでそちらを使う

yarn version --patch

オプション部分は--minor--majorの他、prereleaseなどもあるので適宜選択する

このコマンドを叩くとpackage.jsonのversionが適切に変更された上でcommitが作成される
さらにgitのtagもそのバージョンで付与してくれる

この特徴を活かしてGitHub Actionsでいい感じの運用をすることにした
具体的にはtagのバージョンが変更された時のみそれを検知してnpm publishを行う

その他にもリリースノートの作成などを自動化する設定を行なったので以下で見ていく

GitHub Actionsによる運用の自動化

ここでは2つの自動化機能を取り上げる

・PR作成時に自動でlabelを付与する
・リリースノートの自動作成とnpm publishの自動化

PR作成時にlabelを付与する

PRが作成された時にfeaturerefactorfixなどのlabelを自動的に付与する
これ自体でも意味はあるのだが、この次に取り上げるリリースノート作成時にこれがとても役に立つことになる

まずworkflowsに以下のようなymlを定義する

name: PR Labeler

on:
  pull_request:
    types: [opened]

jobs:
  pr-labeler:
    runs-on: ubuntu-latest
    steps:
      - uses: TimonVS/pr-labeler-action@v3
        with:
          configuration-path: .github/pr-labeler-config.yml
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

次に.github配下にpr-labeler-config.ymlという名前で以下のようにlabelの設定ファイルを記述する

Description: >
  If you were working on fix/issues#1 branch,
  pushing to that branch will auto label 'fix'.
  ex) label_name: ['branch_name']

feature: ["feature/*", "feat/*"]
fix: ["fix/*", "bug/*", "bugfix/*"]
chore: "chore/*"
documentation: ["docs/*", "doc/*"]

これによって例えばbranchの名前がfix/some-bugだったらfixのラベルがPRに付与されることになる

branch名が上記に対応していないものになっていない場合は意味がなくなってしまうので、それを強制させたかったらcommitlintを別途設定する必要がありそう
今回はそこまでしなくていいかと思い妥協した

リリースノートの自動作成とnpm publish

新しく更新した内容をnpmに公開してアップデートしたいがそれを自動化したい
どうすればいい感じにできるかと考えた結果、gitのtagをトリガーにするのがよさそうという結論に至った

まずバージョンを上げて公開する際には以下のコマンドを叩く

yarn version --patch

これによってバージョンアップのcommitが作られるがその際にそのバージョンでgitのtagが作成される
ただし、prefixとしてvが付与されているのでv0.0.2みたいになる

これを普通にpushしてもtagはremoteに反映されなかったのでオプションが必要
以下のオプション付きでpushすることでremoteにもtagをpushすることができる

git push origin --follow-tags

似たようなオプションとして--tagsというのもあるが、これだとタグのみのpushになって、バージョンアップのコミットそのものがpushされていなかった
両方pushする際には--follow-tagsでpushする

これによってremoteでtagsが更新されるのであとはGitHub Actionsでtagsのpushを検知して動くワークフローを書く
今回やるのはnpm publishとリリースノートの作成

name: release

on:
  push:
    tags:
      - "v*"

jobs:
  release:
    name: release-npm-package
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2
      - name: setup-node
        uses: actions/setup-node@v2
        with:
          node-version: "16"
          registry-url: "https://registry.npmjs.org"
      - name: can-publish
        run: npx can-npm-publish --verbose
      - name: current-package-version
        run: node -p -e '`CURRENT_PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
      - name: release-draft
        uses: release-drafter/release-drafter@v5
        with:
          name: v${{ env.CURRENT_PACKAGE_VERSION }}
          tag: v${{ env.CURRENT_PACKAGE_VERSION }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - uses: actions/cache@v2
        id: cache_node_modules
        with:
          path: "**/node_modules"
          key: node_modules-${{ hashFiles('**/package.json', 'yarn.lock') }}
      - run: yarn install --frozen-lockfile
        if: steps.cache_node_modules.outputs.cache-hit != 'true'
      - name: publish-to-npm
        run: yarn publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}

can-npm-publishはpublishできる条件がそろってないとエラーで落ちる

これをクリアしたあとpublishするpackageのバージョンを取得してGitHubのenvに格納している
その後リリースノートのタイトルと実際に付与するtagを設定している

最後に実際にpublishを行う
NPM_ACCESS_TOKENはあらかじめnpmにログインして取得したあと、secretsに格納しておく必要あり

以上の設定で「バージョンアップしてtagを付与、それをpushする」という操作を行えばpublishまで自動化されるようになった
さらにこんな感じのよく見るリリースノートをdraftで作ってくれる。内容を確認、fixしてリリースするだけでいいので超便利

Screenshot of generated draft release with categories
https://github.com/release-drafter/release-drafter

まとめ

実際に開発を行う際の動作確認方法やバージョンアップ時の運用方法について開発しやすいいい感じにできたと思う

gitのtagとかは自分ではあまり使わない機能だったので非常に勉強になった

リリースノートの自動作成とかできて非常に楽しかった
あとは作りたいものを見つけて実際にライブラリとして公開するだけ。笑

この記事が参考になったからコーヒーくらいおごってもいいぜという方は、以下からサポートいただけると次の記事書くモチベになりますのでよろしくお願いします

Buy Me A Coffee

参考

GitHub
GitHub - release-drafter/release-drafter: Drafts your next release notes as pull requests are merged... Drafts your next release notes as pull requests are merged into master. - GitHub - release-drafter/release-drafter: Drafts your next release notes as pull requ...
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次