NextJS + FirebaseでReact Native Matsuri 2021 公式サイトを開発しました
こんにちは、株式会社g&hというところでエンジニアをしているわたなべゆう(@hmktsu)といいます。
2021年10月2日土曜日に行われるReact Nativeをメインテーマにした、日本で初開催の技術カンファレンスであるReact Native Matsuri 2021の公式サイトを開発させていただきました。
もしよければ先にデザイン的な話について、「React Native Matsuri 2021のデザインを担当しました」というmioさんが書いた記事をご覧になってください。
# はじめに
まずこの記事では細かいコードなどは抜きにして、どういう技術を用いて開発したのかという話をしたいと思います。
## ざっくりとキーワード
・TypeScript
・NextJS
・Recoil
・Firebase
・GitHub Actions
・i18n対応
・nodemailer
・node-canvas
## NextJSとFirebase
最近ではよくある組み合わせとなってきたFirebase Hostingを使ってのNextJS開発。
さらにそこにTypeScriptも添えてという組み合わせが多いのではないでしょうか。
どうしてHostingがFirebaseなのか?
NextJSをよく使っている人ならばそういう疑問が生じるのではないでしょうか。
NextJS開発元のVercelを使えばいいんじゃないか、というお話ですね。
正直なところで言うとVercelであるという旨みがなかったからです。
例えばVercelにできてFirebaseにできないことといえばISR(Incremental Static Regeneration)があります。
(なおISRについての説明は省略させていただきます)
別にブログみたいな動的なコンテンツを用意するわけではないから、SSGしたファイルをFirebaseでホスティングすればいいだけという形になります。
それにどこまで動的かになりますが、動的だったらSSRでいいかなと思っています。
また値段もFirebase HostingないしはFirebase Storageは大変安く、ほぼ無料で使えるので問題がないなと。
さらにいうとReact Native Japanのメールアドレスがgmailだったので、アカウントをわざわざ開設する必要がなかったというのも理由ではあります。
ということで用途的にFirebase Hostingで事足りたからFirebase Hostingを使ったという形になります。
GitHub Actionsと組み合わせるとデプロイが簡単
ローカルでビルドしてデプロイをしてもいいけども、PCをいちいち触ってデプロイするのは面倒ではあるし、そもそもGitHub Actionsが無料で使えるわけだから使わない理由はないわけですしね。
ブランチベースでのCI出しわけを行っています。
開発をするのはhmktsuみたいな適当なブランチで行い、developブランチへPRを出して単純にNextのビルドができるかどうかなどをチェック、developブランチがマージされたらdevelop環境のFirebase Hostingへのデプロイ、mainブランチがマージされたらproduction環境のFirebase Hostingへのデプロイをしています。
さらにGitHub Actionsが完了したらSlackないしはDiscordに通知するようにもしています。
仮に何かが原因で落ちてしまったなどもわかりますので、例えばテスト結果をお知らせするだけという用途だけでもいいかもしれません。
CRA(Create React App)でない理由は?
こちらもよく話題になる話。
前述したHosting部分で動的ではないよと述べていたので、ということであればCRAでもいいじゃないかという話になります。
個人的な趣味ですという回答でもよいのですが、ある程度の理由は実はあります。
・React RouterでルーティングするよりもNextJSの方が簡単
・Node部分を書く必要がある処理があったので、Functionsを使うよりもNextJSのサーバサイドを使った方が簡単
nodemailerを使ってメールするとか、実はその裏でnode-canvasを使って画像生成やっていたとか、SSRするページがあったりとかはしたんですけど、参加登録までの導線整理など諸々があり、一瞬ではありましたがそれらサーバサイドが関わる部分を使っていたというのも理由です。
サーバサイドも書くことがある、ルーティングを直感的にやりたい、AWS S3やFirebase Storageなど単純なHTML/CSS/JSしか置くことができないサーバではないならば、NextJSで問題ないかなと思います。
## 他言語対応の実装
React Native Matsuri 2021公式サイトではトップページなど主だったページについては日本語英語対応をしています。
i18n対応
i18n対応は大きく分けて2つほど対応方法があります。
1つはhttps://example.com/jaのように言語コードをURLに使う方法で、サブドメインでやっている場合もあればURLの中に使うという形ですね。
もう1つはURL自体は何も変わらないけども、cookieであったりstateで持っている言語コードに応じて出す文字列を変更するというものになります。
React Native Matsuri 2021公式サイトではNextJSのSSGを使っているからURLの出しわけとの相性は比較的よいと思ったので、URLに言語コードを使う方法にしています。
Recoilを使って言語情報をグローバルに保持
React Native Matsuri 2021公式サイトでは、日本語英語対応をするために現在どの言語を選択しているか?という情報をグローバルに保持しておきたいので、そのための用途としてRecoilを使用しています。
Recoilは人によって解釈の違いはありますが、個人的にはグローバルなstateを持つというイメージに近くて便利です。
もちろんreduxなど他のものでも組むことはできますがreduxで組むには大袈裟すぎる、useContext + useReducerも言語情報という名のstringを持つだけなのにちょっと書き方がややこしい、などなど個人的な感想があった上での選択にはなりますが。
RecoilならばuseStateを書くような形で記述することができるので、Recoil + カスタムフックという形でグローバル風に呼び出すということを簡単に記述できました。
その言語情報を元に、SSGするないしはページ遷移をする際にURLを出しわけするという形になります。
## その他
nodemailerとかnode-canvasなどが一部言及されていましたが、これは参加申し込みを押すとnodemailerを通してメールを送信 + GitHub Loginのモーダルが出て、Authorizeすると画像と名前を取得して下記のような画像を作ってくれるという一連の流れを実装してくれるものでした。
HTMLのcanvasを使ってビジュアルを見ながらせこせこ調整して開発し、そのコードをNodeとしてサーバにアップするだけで出来上がるというのがnode-canvasを使った画像生成の流れになります。
なのでImageMagickなどを使うよりも開発調整をするのは簡単だなぁと思います。
# おわりに
react-native-webで作るぞ!というのもありだったんですけど、アプリを出すわけではないからなぁということでreact-native-webでは作りませんでした。
来年は自分が公式サイト作るぞ!という人や、React Native Matsuriの運営やりたい!という人や、React Native MatsuriだけでなくReact Native Meetupの運営もやりたいぞ!という人はぜひぜひTwitter(@ReactNativeJP)までお声かけをしていただけると助かります。
この記事が気に入ったらサポートをしてみませんか?