npmパッケージを公開した話

前のエントリで作ったuseMediaQueryをせっかくなのでnpmパッケージとして公開してみました。 テストとかパッケージングとか色々やり方を知らなかったので、いい機会だし休み中に勉強がてらにやってみました。

公開したパッケージは以下のURLで確認出来ます。

www.npmjs.com

github.com

今回のパッケージ公開時では以下のことを実現したいと思っていました。

  • TypeScriptによる実装
  • テスト/lint
  • semantic-releaseによる自動バージョニング

TypeScriptによる実装

自分が普段JavaScriptのコードを書く際はいつもES6で書いているのですが、 公開パッケージと言うこともあり、出来れば型宣言も含めて公開できればと思い、TypeScriptで実装しました。 まあ、そんなに大きなコードでもないので、実装する際には所々変数や関数に型宣言を付与するくらいでしか無かったです。

テスト/lint

useMediaQueryは基本的にwindow.matchMediaによって実現しているのですが、この関数をテストコード上で動作させることが非常に困難です。

jestによるテストでは、documentとかwindowまわりのブラウザが持つDOMのAPIはnode上でそのまま動作させることが出来ず、 jsdomというライブラリを利用することでnode上で実行させることが出来ます。 問題として、jsdomではwindow.matchMediaをサポートしていないため、うまくmockを利用してテストコード上で動作させる必要があります。

ちなみにuseMediaQueryはresizeイベントを監視し、都度window.matchMediaを呼ぶことで実現していますが、 メディアクエリの状態が変化したときに呼ばれるコールバックを利用して実現するように改修したいと考えています。 実装自体はそんなに難しくなさそうなのですが、コールバックを発火させるテストが今のところうまく書けてません。

TypeScriptでのいい感じの実装の仕方があんまり分かってないので、そのあたりはtslintに教えて貰おうと思い、 tslintの設定も行いました。

semantic-releaseによる自動バージョニング

バージョン番号の付与の仕方としてsemantic versioningというものがあります。 このバージョン番号の付与を自動化し、適切なバージョンを付与するためにsemantic-releaseを利用しました。

semantic-releaseではコミットコメントから、その変更がパッチなのかマイナーアップデートなのかを自動的に判断し、 それにより適切なバージョン番号を付与します。 また、その際に様々なプラグインを利用することで、GitHubのリリースを作成したり、Changelogを自動生成したり、npmのパッケージを公開したりすることが出来ます。

今回はcircleci上からsemantic-releaseを利用することで、masterブランチが更新されると自動的にnpmへパッケージを公開するようにしました。 ちなみにこちらの動作確認の際に試行錯誤を行った結果、ちゃんと動作するバージョンが1.0.4になってしまいました。

まとめ

元々はReact Hooksのカスタムフックを利用した設計が面白いと言うことで、今仕事で書いているプロダクトで結構カスタムフックを書いていて、 せっかくだし汎用的なカスタムフックはライブラリにするかーと思い、npmパッケージを作ってみました。

カスタムフック自体は大きな1つの関数で、内部でメモ化された関数呼び出しを複数持つことで状態を管理できるようになっているものです。 その仕組み上、カスタムフック内部で持つ個々のメモ化された関数等のテストがちょっと面倒くさそうだなあと感じています。

後はコミットメッセージをConventional Commitsに従って書けば、 semantic-releaseで適切にバージョン番号が管理できることを知れたのは良かったです。 オープンソースプロジェクトのコミットメッセージの頭に良くfeat:とかfix:とか書いてあるのはこれだったのか、と今更気づきました。

やってみればそんなに難しくも無かったので、今後も何か有用そうなカスタムフック作ったら公開できればと思っています。