![見出し画像](https://assets.st-note.com/production/uploads/images/61369406/rectangle_large_type_2_07978394058bca723e234d13ecef70eb.jpg?width=1200)
Now in REALITY Tech #11 REALITY for WEB を支える技術
サーバエンジニアの阿部です。もう9月ですね。月見バーガーの季節です。
9月といえば昨年の今ごろ、海外対応の準備をしていたら September月 という文字列を含むチャットを飛ばしてしまった過去を思い出し古傷が痛みます。Go の time.Month 型を文字列化するとその月の英語名が返ってくるので、time.Now().Month() とかを雑に文字列テンプレートに流し込むと不思議な文字列が爆誕することがあります。ご注意ください。
さて、先日「REALITY for WEB」がリリースされました!
REALITY では Web 開発もサーバチームで担当しています。サーバチームは普段 API サーバの話題が多めなので、今回は REALITY の Web 開発について少し紹介しようと思います。
REALITY における Web 開発
REALITY の Web 開発は Vue.js + TypeScript で行っています。Vue はまだ2系を利用しており TypeScript とはあまり相性が良くないのですが、vue-class-component + vue-property-decorator を利用することで TypeScript ベースで開発を行えるようになっています。型は福利厚生。
Web がどこで利用されているかというと、アプリ内のお知らせやイベントページなどの画面は Web で開発し WebView で表示しています。
ネイティブアプリの機能を呼び出せるインターフェースも実装されており、WebView からでも快適に利用できるように開発しています。例えばイベントランキングでは配信中のユーザをタップすると配信に直接飛べたりします。
REALITY for WEB を支える技術
今回リリースした REALITY for WEB は、アプリ内からではなくブラウザでログインして利用します。
このページには以前からLIVEポイント関連の機能がありましたが、そこに公式番組の視聴・コメントやコイン購入、購入履歴などの機能を追加し装いも新たにリリースしました。最近公式番組はたまにしかやっていないので普段はコイン購入+αくらいのページになっていますが。
コイン購入は今回の目玉機能で、アプリ内よりもお得にコインが購入できます。決済のバックエンドは Stripe です。と言っても我々が Stripe 対応を直接行ったわけではなく、グリーグループの共通基盤システムである gamelib を通して利用しています (参考資料)。
REALITY 側では gamelib のつなぎこみと UI 実装に集中することで、比較的短期間で決済機能を導入できました。REALITY ⇔ gamelib ⇔ Stripeのような構成になるためコントロールできる範囲が少ないなどの難しさもありましたが、決済系に強い方々に協力いただいて開発できるのは心強いです。
Safari の苦労話
やはりフロントエンド開発で大変なのはブラウザ間の挙動の違い。今でこそ IE はほぼ絶滅しましたが、それでもブラウザごとに機能の対応状況は割と違います。
REALITY for WEB では Mobile/PC ともに Chrome と Safari をサポート対象としていますが、普段は Chrome で開発していたため QA の際などに Safari で思わぬ挙動が報告されて頭を抱えたりしました。そんな苦労話をいくつか。
・ブラウザバックするとボタンが反応しない
Safari で一度ブラウザバックをすると、それ以降購入ボタンが反応しなくなるという不具合が報告されました。調べてみると、iOS Safari で history を利用した際にそれ以降 alert() や confirm() が動かなくなるという話を発見。
vue-router を利用した SPA として開発しているので、ブラウザバックすると history API が呼び出されてこれに引っかかってしまったわけですね。ボタンは押せているが、confirm() が実行されずに false が返っていたようです。
仕方ないので iOS Safari では popstate イベントを検出した際にリロードするようにしました。
if (isIosSafari) {
window.addEventListener('popstate', function (e: PopStateEvent) {
window.location.reload()
})
}
これ SPA だとかなり引っかかる話なのでは……。alert() とかを使わず独自のモーダルなどで実装していればハマらないのかもしれませんが、Safari には早めに対応してほしいところ。
・正規表現でクラッシュ
正規表現を使っている処理で Safari だけ何も動かないという不具合の報告が。調べてみるとこのような SyntaxError が発生していました。
SyntaxError: Invalid regular expression: invalid group specifier name
どうやら Safari では後読み (lookbehind) 正規表現に対応していない様子。(?<=A)(B) のように書くと、前にAがあるようなBだけがマッチするというやつです。既存実装で実績のある正規表現が使い回せなくなってしまったので悩みましたが、(?:A)(B) のようにして A がキャプチャグループに含まれないようにしつつ、ロジックも少し付け足して対応しました。
ちなみにこれまで Web のリポジトリにはユニットテストの仕組みがなかったんですが (Go のリポジトリにはあります)、今回の修正はテストなしでは厳しかったので Jest の導入から始め、元の正規表現で通るテストを一通り書いてから修正を始めました。テストは正義。
一応直せたとはいえやっぱりつらいので Safari には早く対応してほしいですね。まだ見つけられていない地雷もありそうで怖いです。
まとめ
今回は REALITY における Web 開発について簡単に紹介しつつ、開発時の苦労話などをしました。Web は専任チームがいるわけではないのでコード基盤の整備が追いついていない部分もあり、サーバはもちろんですがフロントエンド開発にも詳しい人が増えると嬉しいなあ……。
そんな訳で、REALITY では一緒に開発してくれるメンバーを大募集しています! まずは気軽にカジュアル面談から! よろしくお願いします!