2021年の振り返り
By kkoudev
もう2022年に入ってしまいましたが、そういえば2021年の仕事や技術を振り返りをしていなかったので振り返ってみました。
ただ、2020年に比べるとそこまで大きく何かをやったわけでもないので、軽く振り返りつつ仕事や個人的に関心のあった技術について今回は振り返ってみようかと思います。
仕事について
仕事は去年に引き続き mocri というプロダクトの開発を行っています。
エンジニア以外の仕事も徐々に増えてきたこともあってメンバーを増やして今ではエンジニア3人、デザイナー1人、ビジネス1人の計 5 人で開発をしています。
ふと冷静に考えてこのエンジニアの人数でiOS/Android/Browser (&バックエンドとインフラ)の開発を続けられていることは不思議で仕方ないのですが、
なんだかんだReact NativeとNext.jsのアーキテクチャー設計を統一しつつ作れているところが大きいなと思います。
アーキテクチャー設計次第では人数も極限まで絞れる、というのをここ数年で証明できたことは嬉しいことです。(とはいえ本当はもっと人数を増やしたいですけど・・・)
技術について
M1 Macへ移行
きっかけとしては使っていたIntel Macに盛大に水をこぼしたという理由からM1 Macへ移行することになったのですが、
いざ使ってみるとめちゃくちゃ軽くて電池も長持ちするし、AirでもIntel MacのMacbook Proより性能が出ており、凄く使いやすいと感じています。
開発環境のM1 Mac対応については幸い移行タイミングが良かったのかスムーズに進めることができたのと、
現在はIntel Macを使うことの方がデメリットが出始めてきていると感じています。
ちなみにNode.jsでいえばv16からarm64バイナリがあるのでNode.jsはv16以降にするのがおすすめです。
iOSについてはCarthageをxcframeworks化し、Podfileで少々設定を変えればM1対応ができます。
ただSPMを使っているときがネックで、これについてはxcframeworksを含んだSPMであれば問題なく使えますが、
ビルドがarm64対応していないときは素直にRosetta2を使う必要が出てきます。
フロントエンドはNext.jsが事実上のデファクトスタンダードになりつつある
数年前はVueを使ったNuxtの人気が出ていましたが、Reactに比べてTypeScript対応に課題があったことと、Next.jsの存在から再びReactの人気が上がってきたように伺えます。
Next.jsはwebpackの内部処理を隠蔽しており、ほぼwebpackの設定を意識しなくても使えるところも良いです。
また、Core Web Vitalsをあまり意識せずとも上げられるような設計になっていることから、採用しない理由がないくらいに良いフレームワークだと思います。
私の所属している会社でも殆どのプロダクトがNext.jsを採用しつつあります。
Reactの状態管理ライブラリについて
Reactは状態管理が非常に難しいのと、フロントエンドの状態管理については未だにこれといったスタンダードが現在も存在しない状態です。
まだHooksのなかったReactでReduxが多く使われたであろう5年ほど前と比べるとReduxの利用自体は減っていますが、
現在もなお様々な状態管理ライブラリが混在している状況です。
私は過去にReduxの非同期処理の書きづらさで苦労した経験や、Fluxベースの処理は結局冗長になりやすいと感じていたこともあって、長い間MobXを採用していたのですが、MobXもバージョン6が出てからデコレーターベースの実装を排除した影響により、TypeScript利用においては必要なコード記述量が実質2倍になってしまったのもあって新しいバージョンを採用する理由がなくなってしまいました。
そのため去年は移行するならどの状態管理ライブラリか?というのを考えていました。
1. Recoil
Facebookが作成した状態管理ライブラリで一見良さそうかなと思ったのですが、
atomにkeyの記述が必要で、後述する jotai や Zustand と比較した時どうしてもそのkeyの冗長感が拭えないのが正直なところです。
ここがどうしても受け入れられなかったので採用候補からは外してしまいました。
2. jotai
getterおよびsetterのatomを定義し、それをrenderで利用していくという非常にシンプルなライブラリです。
Recoilではkeyが必要ですが jotai では不要です。
複数のatomを合わせて計算する時に set や get が乱立して入れ子になるところが少々複雑性を増している気がしてしまうのですが、
Recoilに比べるとまだわかりやすい処理になっているのではないかなと思います。
3. Zustand
ZustandはStoreを定義し、利用する値のgetterおよびsetterを定義して利用する方式です。
jotaiのatomをStoreというグループにまとめて定義しているようなものだと思えばいいかもしれません。
ただ、jotaiと同様に set や get が複数の関数に乱立するところが少々複雑に見えてしまいます。
とはいえ、これは慣れの問題かなという気もしているので、jotaiのようにatomを個々に定義するよりも
Storeというグループにして定義可能なZustandの方が個人的には好きな設計です。
4. valtio
近年名前を聞くようになった状態管理ライブラリで、MobX5を使ってきた自分から見るとこれが一番筋が良いと思いました。
MobX同様Proxyベースで値の更新を隠蔽してくれているので、単純に値に代入するだけで状態の更新を行えます。
もちろんこれはこれで一長一短なのですが、うまく使えばHooksベースな処理に縛られることなく、Reactのフロントエンド実装を実現できます。
私はオニオンアーキテクチャーをフロントエンド実装で採用していることもあって、
その設計を実現するにはどうしてもMobXのようなProxyベースの状態管理が相性がよかったのでこれに移行したいなと考えているところです。
とはいえ、Recoil、jotai、ZustandのようなatomやStoreベースで更新をしていく状態管理ライブラリが多いというのもあって
それらの方向性から外れた設計になってしまうことはいささか懸念ではあります。
フロントエンドのアーキテクチャー設計について
最近その辺りのブログ記事やTwitterをみていると、フロントエンドでDDDやクリーンアキテクチャーは冗長、という意見がみられます。
多分そう思うのはフロントエンドのアーキテクチャー設計の主流はHooksベースな状態管理であること、Reduxが長い間覇権をとってきたこと、運用と生産性を考慮できたアーキテクチャー設計を体感したことがないor実感するのに時間がかかる、という理由があると思っています。また、印象としてもHooksやReduxと比較し、明らかに異質な存在のようにみてしまうことがあるからかもしれません。
私は以前、まだReduxすら流行っていなかった時代に単にReact+TypeScriptなプロダクトの開発を途中から手伝ったことがあったのですが、
アーキテクチャー設計が全くないために、setStateが乱立するデータの流れが非常にわかりづらいいわゆるスパゲッティコードになっているのを目の当たりにしました。
要はアーキテクチャー設計がない状態で使うReactは(Reactに限らないですが)、利用者の力量によっては簡単にコードをスパゲッティ化してしまう恐ろしいものなのです。
なので、私はアーキテクチャー設計を意識することはフロントエンドにおいても非常に重要だと考えています。
私が今作っているプロダクトはオニオンアーキテクチャーベースで3年前にベースを作ったにも関わらず、スパゲッティ化のような問題は起きていないため
追加開発を続けていく上では堅牢な作りになったのではないか・・・と今になっては思います。
また、アーキテクチャー設計は何事も極端にやると失敗するし、面倒だったり冗長に思えてしまうものなので
落とし所と踏まえてやれば様々なメリットを享受できるものであると私は思っています。
(要するに、冗長性や複雑性を単に増しているだけに過ぎない部分があると思ったらそこは自分で設計ルールを改変してアレンジしてまっても良いのだと私は考えています)
ちなみに私が採用しているアーキテクチャー設計については徐々にアレンジはしていますが、ベースは変わっていないので興味がある方はこちらの記事を参照してみてください。
CSS Modules と CSS in JS
私は前職でエンジニアチームとデザイン部を兼任していたある意味特殊な立ち位置にいたのですが、
デザイン部にいた理由としてはマークアップがある程度出来るからという理由でした。
そんなマークアップする側の自分としてはCSSはCSSとして書けることに意義があると考えていたことや、CSS in JSはどこか邪道だと常に考えていました。(要はエンジニアであるにもかかわらず、マークアップするときの思考はデザイナー寄りの思考でした)
またもう1つの理由としては単純で、速度の問題です。
CSS in JSは結局はJSなので、レンダリング時にスタイルを反映するとなると通常のCSSよりも反映に時間がかかります。
そのため、通常のCSSと同じように速度が出て、かつコンポーネントごとに分離が可能なCSS Modulesを当初採用したのですが、
CSS Modulesはcss-loaderがdeprecatedにしたがっているという話もあるようで、今後何を選定すればいいのかという悩みがありました。
それと、css-loaderを使っているというのもネックの1つであり、StoryboardとNext.jsでcss-loaderのバージョンを合わせるのが結構面倒だったりします。
また、Next.jsがCSS Modulesを推奨している割にはCSS Modulesだけで発生するバグを持っていたりして、
そういう意味でもCSS in JSの方が実は良いのか?という気持ちも出てきて、CSS in JSについていくつか調べました。
結局のところCSS Modulesを現在も使い続けているのですが、
個人的に筋が良さそうだなと思うのは vanilla-extract です。
これはCSS Modulesと同じくCSSファイルを生成してくれるのと、TypeScriptでスタイルをオブジェクト形式で記述するので、
stylelintを入れなくても構文エラーがチェックできるというのはとても良いと思いました。
そのため採用しようか一時的に迷ったのですが、
通常のCSSの記法とオブジェクトスタイルの記法、前者の方が圧倒的に書きやすくないか?というのがあって、
未だに踏み切れてなかったりします。
結局のところ未だに移行していない理由としては、移行メリットをあまり感じていないというところかもしれません。
これについては今後のCSS Modulesやcss-loaderの動向を探った上で決めたいと思います。
インフラをEKSへ移行
こちらの記事にも記載しましたが、3年ほど使ってきたkopsのk8s環境のクラスタバージョンアップに失敗し、限界を迎えてきたので、思い切ってEKSへ移行しました。
EKSへ移行してからはkopsで起こっていた数々の課題を解決できて現在は快適です。
私自身はオンプレ時代からこの業界にいる技術者なのでどこかマネージドサービスを完全には信用できないタイプではあるのですが、
面倒な運用部分を引き受けてくれるマネージドサービスは使い所によってはとても良いなと改めて思いました。(k8sクラスタやDBなどはまさにそうかなと思ってます)
Aurora 3へDBを移行
これは去年末の話で実際に移行したのは年明けなのですが、
データベースをRDS for MySQLではなく、Auroraに移行してみました。
理由としては、Aurora 3 (MySQL 8互換)が登場したことです。
今まではRDSでMySQL 5.7を利用していたのですが、Auroraにしてパフォーマンスを強化しつつ、MySQL 8で使えるようになったWindow関数を使えば集計する際にラクになるかも、というのが移行しようと考えたきっかけでした。
実は長い間AWSを使ってインフラ構築をしていたものの、Auroraを採用することにはどこか抵抗があって採用していなかったのですが、
なんで今まで採用してこなかったのかというくらいにフェイルオーバーが高速でちょっと感動しました。
通常のRDSを使っているとセキュリティーアップデート等があるとメンテナンスをする必要がありましたが、
Auroraを使えばそんな必要もほぼないな・・・というのを実感しています。
ただ、現在使っているAurora 3.01.0はbinlog_formatをROWにしていると急激にメモリリークするバグや、
セッション変数を頻繁に使うクエリがあるとメモリリークをしてしまうバグがあります。
(AWSサポートに確認して発覚しました)
そういった問題はあるので付き合っていくのも簡単ではないかもしれませんが、それ以上に享受できるメリットの方が多かったので自分としては移行してよかったなと思っています。
また、データ移行時に初めてDMS (AWS Database Migrate Service)を使ったのですが、これもめっちゃ便利で感動しました。
2時間メンテにしてmysqldumpをとってそれをインポートして・・・みたいなことを大昔にやっていた私からすると、本当にマネージドサービスは凄いと思います。
こういうサービス運用保守や移行を簡単に実現できていくマネージドサービスの存在をみると
GCPではなくAWSを使っていく理由の1つにもなってくるな・・・と改めて思いました。
Docker Desktopの有料化について
とうとう今月いっぱいでDocker Desktopも無料期間は終わってしまいます。
これについては別途記事を書こうと思っているのですが、私は利用をやめて別環境へ移行しました。
理由としてはその記事にも書こうとは思っているのですが、端的にいうと以下の3点が決めてです。
- Docker Desktop for Macは以前からストレージが遅い問題や、アップデートが重い問題があるので敢えて課金してまで利用するメリットがない
- k8sが1.24からDockerを完全非対応にしようとしている流れがあるので、Dockerの利用を続けていくことで今後問題が生まれそう
- Dockerは現状殆どがイメージのビルドしか利用していないのでbuildahへ移行すれば不要になりそうなのと、podmanやpodman-composeを使えば置き換えできそう
要するにk8sを使っている自分からするとDocker自体を直に使うケースが非常に少なくて、その上で課金までして使い続ける理由がなかったというだけになります。
この詳細についてはまた別途記事を書いてその中で説明していきたいなと思います。
まとめと2022年にやりたいこと
というわけで2021年を振り返ってみました。
2020年の振り返りの時に2021年にやりたいことをいくつか書いたのですが、
GraphQL以外は実現できたのではないかなと思ってます。
今年はフロントエンド利用においてGraphQLの採用にも力を入れられるようにしたいなと考えています。
あとは実際のプロダクトでもつかっている私が作っているbash製のバージョニングツールである ndw と gvw をRust化したいと思っています。
これはRustの練習の意味も込めてなのですが、時間を見つけつつ実施していきたいなと思います。
そんな感じで、2022年も引き続き新しいことに挑戦していきます。