基本的に Google Chrome で開発しない方が良い

自分への戒め。タイトルは極端だが、本気でそう思っている。

※ 本記事は Google Chrome での開発を否定するわけではありませんし、可能な限り色々な ブラウザ/バージョン/OS で動作確認するのがベストです。が、ブラウザの挙動に依存する Website を作っており、全てのブラウザで確認する余裕が無い場合、 Google Chrome ではなく別のブラウザで開発する方がバグが早期に発見できるのでは？という甘えも許されるのでは？という提言です。

# 概要

例えば、 Chromium をベースとするブラウザ（以下 Chrome） で普段開発していて、

「OOOにログインできない」

などという問い合わせがユーザーから来て、色々調べた結果、

- iPhone Safari で見るとボタンが隠れていた
- Safari on Mac だと JS でエラーが出る
- Firefox だとここで止まる

みたいなことがあるとする。「頼むから Chrome 使ってくれ」と思いつつ、ユーザーにそんなこと言うわけにもいかないので、その度に該当のブラウザを開いて修正するが、これって不毛じゃないかと思い始めた。

色々調べたり考えた結果、そうしたエラーの大半は、 Safari や Firefox が悪いわけではなく、そもそもコードが良くないことが多いことに気づいた。 「Safari で動かない」ではなく「Chrome でのみ動いている」状態だった。

- Chrome は優しすぎるのではないか
- Safari くらい厳格に HTML をレンダリングしてくれる方が良いのではないのか
- Chrome に甘えている自分はエンジニア失格なのでは
- **そもそもコードには厳密な型チェックを導入しているのに、なんで優しいブラウザでわざと開発するのか。** 片手落ち！

という理由で、なるべく開発時は Chrome ではなく、 Firefox を使ことにした。

※ Safari じゃない理由は、宗教上の理由で Arch Linux を普段使いしているためです

# 経緯

今取り組んでいる仕事は、フロント・バックエンド全て TypeScript で、 WebRTC を使うサービス。 ( [Remotehour](https://remotehour.com/?utm_source=referral&utm_campaign=qiita_acro5piano-no_chrome) UTM パラメータ 入れてますがご了承ください)

バグを防ぐために下記のような取り組みをしている。

- TypeScript を厳格に設定
- GraphQL + Apollo Tooling を使って型安全な API に
- ESLint でエラーになりそうな部分を確認
- コードレビューによる人力でのコード確認
- パターンが多い箇所はユニットテストを実施
- Storybook + Chromatic によるコンポーネントのスタイルチェック
- 上記を全て CI 上でチェック
- [リリースノート](https://hackmd.io/@remotehour/remotehour-release-notes)を作り、変更点を一覧化
- ステージング環境で一通り変更箇所を確認
- Rollbar を使ってエラーを通知
- AWS CloudWatch でアラートを設定

ここまでやっても、今まで実際にあったエラーとしては

- `navigator.mediaDevices.enumerateDevices` の前に `navigator.mediaDevices.getUserMedia` を呼ばないとエラーになる (Safari, Firefox)
    - そして、その間に 500ms 程度 Delay を入れないと取得できない （Firefox)
- `navigator.mediaDevices.getUserMedia(条件)` は、条件によっては例外が投げられる (Firefox, Safari)
- 音声がバグる (Safari 14.0.1)
    - 最初 iOS で発生するバグかと思って探したけどヒットしなくて時間消費した。
    - 実際には iOS のバージョン関係無くて、 [Safariのバグ](https://github.com/twilio/twilio-video.js/issues/1337) だからどうしようもない。
- Windows / Linux 等の端末において、他のアプリケーションが排他的にカメラを利用している場合の `navigator.mediaDevices.getUserMedia()` の挙動
    - Firefox はエラーを出す
    - Chrome はエラーを出さない。そもそもザルすぎて `navigator.mediaDevices.getUserMedia()` しなくても Device Label を取得できるｗ
- [DetectRTC](https://github.com/muaz-khan/DetectRTC) の初期化を複数回実行すると、エラー (Firefox, Safari)
    - Safari の場合、[音声が聞こえなくなる](https://github.com/twilio/twilio-video.js/issues/1392#issuecomment-808297532)
    - Firefox の場合、エラーになるので進めない
    - Chrome はスルー。 ザルすぎｗ
- `new Date('invalid date')` が例外を投げる (Safari)
    - React のレンダリング中とかにやると致命的
- その他、プライバシー守ります的な設定（特に Firefox）

など、およそユニットテストとか型チェックとか、そういうテクニックでは改善がかなり難しいことだった。逆に言うと、静的解析で潰せるレベルのバグがあまり起こってない、というのもあるかもしれない。

Chrome は色々よしなにやってくれるので、開発時に起こりうるバグに気づかないことがある。 頑張ってテスト書いても、結局時間取られるのはそのバグ対応。だったら、最初から厳格なブラウザを使って開発すべきなのでは。ユーザーに迷惑もかけないので。

特に iPhone Safari が盲点になりがちで、自分は普段モバイルでは Chrome on Android を使っているので、なかなか気づかないことがある。
これに関しては難しい。 PC は Arch Linux だから Safari 使えないし。Android では Chrome と Firefox で確認して、 Safari 系統は Apple 製品使ってる同僚に頼むか...

社内システムとかは例外かもだけど、結局 Chrome の仕様変更や互換切りとかで突然バグったりする可能性もあるから、なるべく厳密にチェックしてくれるブラウザで普段から確認した方が良いと思う。むしろ Chrome が特殊と思った方が良いかも。

あと、普段使いしないブラウザの方が、 Google ログインとかもしてないから、例えばサインアップ時のフローの欠陥とかに気づきやすいというのもある。
逆に Chrome は普段から使ってるからすぐバグには気づくし、 Firefox で動いてたら Chrome でも動くことが体感多い気がする。
さらに、 Firefox は普段使いしてない故に拡張機能とかも少ないから、原因の切り分けとかもやりやすいと思う。

Firefox Developer Edition にしようかな。あんま違い分からないが。

[追記]

Firefox は Xremap というツールが使えなかったので、 Konqueror という Firefox の亜種でテストすることにした。KDE という Linux デスクトップ環境で動作するもの。