真面目にOSSを公開する際にやってみたこと・意識したこと
先日初めて真面目に自分のコードを OSS として公開する機会があり、色々試行錯誤したのでまとめます。
何を公開した?
Vue Word Highlighter という Vue.js のコンポーネントライブラリを公開しました。
機能はとても単純で、文字列と検索クエリを渡すと検索クエリに合致した文字をハイライトする(<mark>
タグ又は任意のタグ囲む)というものです。
自分なりに良い感じに使えるコンポーネントが出来たので、せっかくならば多くの人に使ってもらいたいと思い以下で記載する諸々をやってみました。
公開までにやってみたこと
🗒 READMEをちゃんと書く
OSS の顔と言ったら README なので、ひと目でちゃんとしてそうな OSS 感を出すために README は整備しました。
ロゴを作る
Google Font で良さそうな書体を探し一部をハイライトしただけの単純なものですが、ライブラリのロゴを作成しました。ロゴの完成度はともかく、あるのとないのでは README の印象が大分変わると思います。
Shields.ioのバッジを貼る
Shields.io の API で CI の状況や npm の download 数などのバッジを作りました。最新バージョンがなんなのか、どれくらい利用者がいるのかひと目で分かって良いです。
サンプルコードは多めに。丁寧に使い方を書く
初めて見た人が使いやすいように、Install から簡単な使い方、オプショナルな設定まで丁寧に書いてみました。英語は、DeepL 翻訳全開なのであっているか自信はないですが、サンプルコードを多めに書くことで雰囲気は伝わるのではと思います。
🖥 すぐ使えるデモサイトを作る
何か機能を試す際、いちいちローカルに落とすことなくデモサイトでサクッと試せると便利です。
vue-word-highlighter でも専用のデモサイトを力を入れて作りました。
デモサイト自体も同リポジトリで管理し、GitHub Actions で GitHub Pages にデプロイしているので低コストです。
また、デモサイト以外にも実際にコードを書き換えながら試せる場所があると便利かなと思い Code Sandbox も用意しました。
💯 CI環境を整備する
今後もメンテナンスを続けていきたいと思ったので CI 環境を整えました。
ESLint、Prettier、Commitlint と husky & lint-staged を組み合わせ、コミット時のコード・コミットメッセージの整形を行っています。
また、UT として Vue3 系と 2 系のテストもほぼほぼ全ケース網羅して書きました。
リンターと UT は毎プルリクエストごとに GitHub Actions で実行しています。
UT があることでライブラリバージョンアップのプルリクエストを安心してマージできたり、実際に実装のバグに気づけたりと導入の手間以上の利得をすでに受けている気がします。やっぱりテストは大事ですね。
🚴 CD環境を整備する
npm モジュールの公開手順も簡略化するため、CD にも力を入れてみました。Release ブランチにマージすると GitHub Actions で semantic-release が起動し、自動的に GitHub のタグの更新とリリースノートの作成、npm への公開が行われます。
これは本当に便利で、今まで手動で公開していたのが信じられないくらいです。手動で公開していた際は、タグの打ち間違えやバージョンアップのミスを度々やらかしていたのですが、それも全くなくなりました。
🏞 OG Imageを設定する
Twitterでシェアされた際に、OG Imageがあると見栄えが良いです。ロゴと簡単な紹介文をあわせただけですが作成してみました。
設定はリポジトリのSettings
> Social preview
から行えます。
⚖️ 既存OSSとの差別化を考える
機能はとても単純で、割とよくある UI なので類似ライブラリは色々ありました。それらと同じものを公開しても、使ってもらえる可能性は低いので、Vue3 でも Vue2 でも使えるという点で差別化を狙いました。
今は Vue2 から Vue3 への移行期で、新規に追加する Plugin については移行時に障害とならないかを検討するのではという予想です。
バージョン間の差分の吸収は Vue-demi を内部的に使って実現しています。
📁 ディレクトリ構成を整理する
リポジトリには、実際に npm パッケージとしてリリースするコンポーネントと、GitHub Pages で公開するデモサイト、vue2 系と vue3 系のテストと少し用途の違うものがまとめられています。当初は全ての依存モジュールをルートの Package.json で管理し、ディレクトリもあまり分割していませんでした。
しかし、それだとリポジトリルートの見通しが悪く、依存関係もわかりにくかったのでモノレポ的にディレクトリを切って整理してみました。
.
├── example # デモサイト
│ ├── package.json
│ └── ...
├── tests-vue2 # Test 2系
│ ├── package.json
│ └── ...
├── tests-vue3 # Test 3系
│ ├── package.json
│ └── ...
├── vue-word-highlighter # パッケージ本体
│ ├── package.json
│ └── ...
├── package.json
...
yarn のワークスペース機能を使って、それぞれのディレクトリで package.json を作り npm モジュールは個別に管理しています。
結果としてリポジトリルートの見通しが良くなり依存関係も分かりやすくなったので良かったです。
🍱 依存モジュールの更新環境を作る
依存モジュールも継続的にメンテナンスするため、自動的にアップデートのプルリクエストを作ってくれる Renovate を導入しました。
今までは GitHub 公式の Dependabot を使っていて、Rnovate は初めてだったのですが、Renovate のほうがバージョンのピンを打ってくれたり、関連モジュールのバージョンアップをまとめてくれたり使い勝手が良いなと思いました。
📣 広報を頑張る
OSS を作っても、存在を知ってもらえなければ使ってもらえないので、告知もやってみました。主に行ったのは Twitter と Plugin まとめサイトへの登録です。
Made with Vue への登録申請と Awesome Vue のリポジトリへのプルリクエストを送りました。
2021/08/16 追記
hiroppyさんに以下アドバイス頂きました。
への投稿も良さそうです。
終わりに
以上、OSS 公開までにやったこと諸々でした。
どれくらい効果があったのかはわからないですが、実績的には公開後 2 週間ほどで 27 スター、npm のダウンロードも 2K となったので今まで公開したリポジトリの中ではトップクラスの伸びでした。
今後もメンテしてより良いパッケージにしていきたいです。
Discussion
些末ですが、一部Vue2 が Vu2 になっている箇所がありました。
コメントありがとうございます!修正します🙏