ライブラリ自体のバグに遭遇したときにとるべき行動

https://qiita.com/laineus/items/00edd8a7abdb336cde3f

---

「ライブラリ自体がバグってるなら俺にはもうどうすることもできん！」
「OSS活動なんてごく一部のつよつよエンジニアだけができるんでしょ？」

って思っている方も、諦めるのは早いです。

ライブラリ側起因の問題でも解決できるかもしれませんし、もしかしたらライブラリに貢献できるかもしれません。

# 1. 調査

:::note info
まずは問題をよく調査することが重要です。
問題の原因が詳しく理解できているほど、このあとにとれる手段も広がっていきます。
:::

## ライブラリのバグなのか見極める

発生している問題が本当にライブラリのバグによるものなのか、自分のコードに問題があるのかを見極める必要があります。

そのためには、自分のプロジェクトのコードをひたすら削っていきながら、**最小限の再現コードを作成**します。

この最小限の再現コードは後で色々と役に立ちます。

## ライブラリのバージョンを変えてみる

ライブラリのあるバージョンから発生した不具合の可能性があります。

**まずはバージョンを最新に**変更して、既に修正済みでないかどうか確認しましょう。

最新バージョンでも発生する場合、**今度は古いバージョンに**どんどん遡っていきましょう。

**どのバージョンから発生するかを特定できた場合、非常に有益な情報となります。**

## ライブラリのソースコードを読んでみる

これはとても難しい話に聞こえるかもしれません。

僕も以前は、「ライブラリって雲の上の神みたいなエンジニアたちが作っていて自分には到底理解できないもの」みたいに思っていましたが、実際は結局人間が書いているものなので、案外理解できたりします。

大きなライブラリだと、問題が起きている場所を特定するのに時間がかかるかもしれません。

先ほどの工程で、**あるバージョンから発生した不具合だと特定できている場合**、発生箇所はかなり絞り込むことができます。

**前後のバージョンの差分を見てやれば、必ずその中に問題に繋がっている変更があるはずです。**

愚直にやるなら、それら差分を一つずつ戻しながら、不具合が治る箇所を絞ってもいいと思います。

発生場所を特定できたら、何が起こっているのか概ね理解できてくることと思います。

## ライブラリのソースで実験してみる

自分のソースであれば、途中にログ出力を仕込んだりしながら詳しくデバッグができます。

ライブラリ側のソースでもそのような感じのデバッグをしたい場合、該当のリポジトリからソースを手元にクローンし、それをインポートするようにします。

1つ目の方法はnpm linkを使って読み込むことです。

https://qiita.com/k_kind/items/b3d04bd5a47ee26b6e2d

あるいは、ローカルのディレクトリを直接してインストールする方法です。

```
$ npm install ../library
```

package.jsonに以下のような差分が発生するイメージです。

```diff:package.json
{
  "dependencies": {
-   "library": "^1.2.3"
+   "library": "../library"
  }
}
```

 この方法だと変更するたびにnpm installしなおす必要があります。

 また、ビルドツールがnode_modules配下の変更を検知しなかったり、キャッシュが効いたりしてしまい、変更がうまく反映されない場合があるのでご注意ください。

# 2. 問題の解決

自身が直面している目先の問題を乗り越えるための暫定的な対応方法をいくつかご紹介します。

## 問題の起きないバージョンを使う

バージョンを戻しても大丈夫な場合、一時的に古いバージョンをインストールして使うことも方法の一つです。

新しいバージョンには、セキュリティアップデートや別の不具合修正などが含まれている可能性もあるため、古いバージョンに戻す際はその点にも注意しましょう。

## 自分のプロジェクト側で暫定対応

先ほど調査して分かった情報を元に、
利用側で不具合がある前提で動くコードに修正したり、

```js
import Library from 'library'

const lib = new Library()

/**
 * Library v1.x.x 以降getValueがstringになってしまう不具合があるためNumberに修正
 * TODO: ライブラリ側が修正されたらアップデート https://github.com/...
 */
const value = Number(lib.getValue())

if (value > 100) {
    // ..
}
```

ライブラリ自体の挙動を外側から無理やり改造したり、

```js
import Library from 'library'

/**
 * Library v1.x.x 以降getValueがstringになってしまう不具合があるため暫定対応
 * TODO: ライブラリ側が修正されたらアップデート https://github.com/...
 */
Library.prototype._getValue = Library.prototype.getValue
Library.prototype.getValue = function () {
    return Number(this._getValue())
}
```

といった暫定的な対応を差し込むことで目先の問題を解消できます。

:::note warn
後で正しい修正が行われるべきなので、それが分かるようなコメントを忘れないようにしましょう。
:::

## ライブラリ側で暫定対応

外側からは修正できない問題の場合、ライブラリ自体を修正する必要があります。

**本家リポジトリに影響を与えずに変更できる方法がありますのでご安心ください。**

ライブラリのリポジトリへ行き、Forkしましょう。

![スクリーンショット 2024-02-06 120028-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151137/bb27d5da-f7b8-9aae-0e31-3b5bfe558712.png)

Forkすると、自分のアカウントにリポジトリが丸ごと複製されたような状態になり、そちらに自由に変更を加えられるようになります。

Forkしたほうのリポジトリを手元にクローンして好きなように修正しましょう。
適切な修正が難しい場合、暫定的な修正の仕方になってしまってもいいと思います。

修正が終わったら、パッケージをgithub経由でインストールして差し替えます。

```
$ npm install git+https://github.com/your-name/library.git
```

package.jsonに以下のような差分が発生するイメージです。

```diff:package.json
{
  "dependencies": {
-   "library": "^1.2.3"
+   "library": "git+https://github.com/your-name/library.git"
  }
}
```

### 補足

:::note warn
Forkしたライブラリでブランチを切って修正したあと、GitHubの画面上からプルリク作成のリンクを踏むと、デフォルトのマージ先が自分のForkしたリポジトリのmainブランチではなく、本家リポジトリのmainブランチに向いてしまいます。

**Forkしたリポジトリでプルリクを作る際はマージ先をよく確認しましょう。**
:::

## 別のライブラリを使う

使っているライブラリが長期間メンテナンスされていないようであれば、これを機に別のライブラリに乗り換えるのも方法の一つです。

# 3. ライブラリへの貢献

先ほどまでの対応で、自分たちのプロジェクトでの問題は解決できたと思いますが、本家ライブラリ自体には問題が残ったままです。

ライブラリは、バージョンが上がるにつれて**不具合が勝手に治っていくかのように感じてしまいますが、実際は誰かが問題を報告し、誰かが直している**のです。

:::note info
**お世話になっているライブラリに貢献できるチャンスなので、ぜひ挑戦してみましょう。**
:::

## リポジトリにissueを建てる

修正までできなくても、**問題を報告するだけでも貢献に**なります。

対象のリポジトリで**Contributionの手順が示されていれば、それに従いながら**問題を報告しましょう。

示されていない場合、

- 問題の概要や詳細
- 発生バージョン
- OSやブラウザなどの環境
- 最小限の再現コード

などを含めてissueを建てましょう。

再現コードは、自分のプロジェクトのロジック等をそぎ落とした最小限のコードにし、CodePenやJSFiddleなどのすぐに確認できる環境に公開してそのURLを掲載するのが親切だと思います。

## リポジトリにプルリクを建てる

コードの修正も行えそうな場合、プルリクを作成しましょう。
こちらも対象のリポジトリのContributionの手順に従ってください。

示されていない場合、ライブラリのコーディングスタイルを遵守したり、テストを書いているようであれば、修正箇所のテストを追加したりしましょう。

もしかしたら、マージされずに他の方法で修正が行われることもあると思いますが（[ちょうどいい事例記事が投稿されてました](https://qiita.com/YmBIgo/items/264f6ec7a05d1a120306)）、それでもきっと役に立っているはずです。

# OSSにコミットすることのメリット

## エンジニア界隈がより便利になる

現代のエンジニアコミュニティは、便利なライブラリや有益な技術記事であふれており、ほとんどのエンジニアがそれらの恩恵を受けてきたはずです。

これは、これまでたくさんのエンジニアが界隈全体への貢献意識をもって行動してきたことが積み重なった結果だと思います。

もし今時間をかけて不具合報告を送ったりしても、即時的な見返りを得られるわけではないかもしれませんが、**こういった小さな貢献意識と行動こそがとても大事**だと思っています。

## エンジニアとしての実績になる

OSS活動としての経験があるということは、エンジニアとしての価値を少し高めます。

実際、自身が採用に関わっていた際は、個人開発でもOSS活動でも、業務外での活動があるエンジニアにはやはり興味を惹かれました。

また、Vueのソースコードには僕の書いたちょっとした修正が存在するのですが、自身が転職活動をする際もネタの一つとして活用することができたりしました。

# おわりに

お読みいただきありがとうございました！

ご参考になれば幸いです。

---

https://qiita.com/laineus/items/b49a6de8cedeae8f90e3

https://qiita.com/laineus/items/7a8980d0d8af69161cf3

https://qiita.com/laineus/items/91101002201a67b38a68