マルチプロダクト戦略を掲げてプロダクトを急速に増やし続けている SmartHR のフロントエンド領域について、2018年から SmartHR に参加しているフロントエンドエンジニアの nabeliwo と技術顧問の koba04 が、これまでの振り返りと今後の展望を話しました。
SmartHR のフロントエンドでどんな技術が使われてきてどんな課題と向き合ってきたのか、そして今現在取り組んでいる課題や SmartHR ではどんなフロントエンドエンジニアが求められるのかなど、幅広いテーマが出てきました。
この記事ではその模様をお届けします。
目次
- フロントエンドの Rails からの脱却とフロントエンド領域の確立
- SmartHR UI の誕生
- プロダクトの急増
- 複雑化する技術課題
- テストの整備とロジック共通化の取り組み
- Next.js の導入
- 新たな技術的挑戦
- フロントエンドミーティングの見直し
- Next.js App Router との向き合い方
- SmartHRのフロントエンドの未来と求められるエンジニア像
フロントエンドの Rails からの脱却とフロントエンド領域の確立
nabeliwo:今回の対談の目的は、SmartHRのフロントエンドの規模やチームの変遷、開発体制や技術要素などについて話し、SmartHRへの転職を検討してくれているエンジニアの方に弊社のフロントエンドが自分に合うかどうかを判断する材料にしてもらおうというものです。時系列に沿って、koba04 さんが参加されたところから、現在までのフロントエンドチームの成長と技術的な変化をお話しできればと思っています。
koba04:はい。
nabeliwo:僕は2018年1月にSmartHRに入社しました。そして2018年11月に koba04 さんがジョインしました。この時、テックブログを出したのを覚えていますか?
koba04:覚えています。
nabeliwo:その記事では、SmartHR のプラットフォーム化の話や、React、Redux、TypeScript、Atomic Design といった話題を取り上げていましたよね。チーム規模で言うと、フロントエンドエンジニアは僕含め2人だけでしたし、プロダクトも「SmartHR」と「文書配付」の2つだけでした。React も当時は導入したばかりで、SPA (Single Page Application) ではなく MPA (Multiple Page Application) の中で各ページごとに React を使うという状態でしたね。この時期のフロントエンドチームの印象はどうでしたか?
koba04:当時はスタートアップの初期段階という感じで、全員がサーバーサイドとフロントエンドの両方を担当している状態でした。nabeliwo さんのようなフロントエンドに強いエンジニアが入ってきて、「ここから本格的に作っていくぞ」というフェーズでした。なので、まだフロントエンドが確立されていない印象が強かったですね。
nabeliwo:たしかに、当時は Rails スタートアップあるあるの「脱 Sprockets」から始めましたね。そのあとkoba04 さんがジョインした直後に「カスタム社員名簿」と「分析レポート」という新しいプロダクトもスタートしました。特に「カスタム社員名簿」では初めて Express を使った BFF (Backend For Frontend) を導入しました。当時は Next.js もまだ一般的ではなかったですよね。
koba04: そうですね。まだまだ Next.js が普及していない時期で、SSR (Server Side Rendering) を自前で対応する必要がありました。React 自体もまだシンプルだったので、SSR もある程度自分たちで作ることができましたが、今ではだいぶ複雑になってしまってあまり現実的ではないですね。
nabeliwo:その頃は「renderToString」などを使っていましたね。一方で、「分析レポート」は SPA で当時から見たら特殊なアーキテクチャを採用していた記憶があります。若干クリーンアーキテクチャの要素を取り入れていましたよね?
koba04:そうですね。「分析レポート」はプロダクトとして複雑になることが予想されていたので、他のプロダクトと比べて慎重に設計していましたが、スケジュールがタイトだったため、そのバランスを取るのが難しかったですね。
nabeliwo:たしかに、チャートやグラフの描画があったり、それらの配置をぐりぐり動かせたりとインタラクティブな要素が多く、かなり複雑なアプリケーションでしたね。
この時期は月2回程度オフラインで集まり、直接相談しながら進めていたことが印象的でした。その場でコードを見てもらったりとか、すごく相談しやすかったですね。
koba04:そうですね。月2回の出社は少ないですが、その分、密度の濃い話ができたと思います。フロントエンドのメンバーが少なかったので、コミュニケーションが取りやすかったですね。
SmartHR UI の誕生
nabeliwo:その時期に SmartHR UI が誕生したのですが、誕生にあたってはkoba04 さんのサポートが大きかったと感じています。
koba04:私はESLint の設定周りや、OSS としての公開などをサポートしていました。当初はエンジニアが共通化を進めていただけでしたが、今ではすっかり成長しましたね。
nabeliwo:たしかに、最初は非常にシンプルなライブラリでしたが、今ではアクセシビリティなどがしっかりと考慮されたデザインシステムにまで広がっていますね。
koba04:React が広く使われるようになり、他社でも同様のコンポーネント共通化が進む中、SmartHR UI はうまく浸透しましたね。
nabeliwo:SmartHR UI が浸透した理由は、やはり新しいプロダクトが次々と生まれ、その中で必要性が高まっていったからだと思います。また、エンジニアとデザイナーが協力して、デザインシステムとして成長させていったことも大きかったですね。
koba04:そうですね。アクセシビリティやその他の要素も加わり、SmartHR UI は大きく変わっていきました。
プロダクトの急増
nabeliwo:次は、2020年頃の話をしていきたいと思います。この時期、新たに5つほどのプロダクトが作られました。具体的には、「年末調整」「従業員サーベイ」「届出書類」「組織図」「人事評価」の5つです。この頃になると、フロントエンドエンジニアの人数が12人に増え、koba04 さんが入ってから約2年間で10人ほど増員されました。
ところで、この頃から koba04 さんが月2回の稼働から週一稼働になったのですが、その経緯について覚えていますか?
koba04:正直、なぜ週一になったのかはあまり覚えていませんが、本業とのバランスを見ながら決めたのだと思います。
nabeliwo:サイボウズで正社員として働きつつ、毎週木曜は SmartHR の方で稼働していたという形でしたよね。そんなことできるんだと思ってました。
koba04:今でもそういう人はちらほらいると思いますが、当時は特に珍しかったかもしれませんね。
nabeliwo:我々にとってはとてもありがたかったです。その後、2020年にコロナの影響でフルリモートになりましたが、オンラインでの相談やコミュニケーションに変化はありましたか?
koba04:やはり難しくなった部分はありました。出社していた時は、直接会って相談したり、一緒にご飯を食べたりすることで、自然な流れでコミュニケーションが取れていましたが、オンラインになると、特に新しく入社した人とは相談しづらくなりました。フロントエンドのエンジニアが増える中で、相談しやすいのは元々オフラインで一緒に働いていた人たちが中心で、オンライン環境に慣れるまでには時間がかかったと思います。
nabeliwo:たしかにそうですね。フロントエンドミーティング(フロントエンド領域の情報共有をする場)も koba04 さんが参加してから始まりましたが、最初は3〜4人で集まっていましたよね。
koba04:はい、最初はファミレス席と呼ばれる社内の小さいテーブルのところで少人数でやっていた記憶があります。
nabeliwo:その時期、採用関連でも koba04 さんの存在が大きかったです。今うちで活躍しているフロントエンドエンジニアの何人かは koba04 さんをきっかけに SmartHR に興味を持ってくれましたよね。また、React.js meetup を弊社を会場にして開催するなど、koba04 さんのおかげで React 界隈での認知度が上がりました。
複雑化する技術課題
社内では、フロントエンドエンジニアが12人に増えた一方で、プロダクトも増えたため、一つのプロダクトにつけるフロントエンドエンジニアは少ないままで、プロダクト開発は特に楽にはなっていませんでした。例えば、「従業員サーベイ」や「人事評価」では専任のフロントエンドエンジニアがいなくて、バックエンドのエンジニアが React を使って開発していました。この頃なにか相談されたこととかありました?
koba04:「人事評価」については、フロントエンドエンジニアが途中から参加して一緒にリファクタリングを行っていました。SWR の導入について相談を受けたこともありましたね。
nabeliwo:SWR が何かというのを説明していただいても良いですか?
koba04:SWR は React の hooks という仕組みを使ったライブラリで、Vercel という会社が提供しています。データをサーバーからクライアント側に取得してキャッシュしたり更新したりというのをやってくれるもので、そこに自分はコントリビュートを何故かいっぱいしていて、今一応メンテナーになっています。「人事評価」の開発途中に出たリクエストを元に SWR に機能を追加したこともあります。
nabeliwo:良い話ですね。最初に「人事評価」に SWR を導入した経緯について教えていただけますか?
koba04:サーバーからのレスポンスも含めて状態管理がとても複雑になってしまっていて、そこをクリーンにしたいというところで、どこでステートを持つかの整理の一環で入れたって感じですかね。
nabeliwo:SWR をグローバルステートとして使うというのも、一応使い方としてはあるんですよね。
koba04:そうですね。ただ公式がサポートしてるかというとけっこう怪しいところはあるんですけど、パターンとしては認識している感じです。グローバルな状態管理はそんな複雑じゃないのに、専用のライブラリを追加で入れるよりもバンドルサイズを減らせるし、簡単なユースケースでも React の組み込みの Context とかよりは効率的に使えるっていうところで、使うのもありかな思っていました。
nabeliwo:なるほど。「人事評価」は最初は MPA でしたが SPA 化する動きはありましたか?
koba04:将来的にはそうしたいという話はありましたが、まずはリファクタリングとテストの整備が優先されていました。
テストの整備とロジック共通化の取り組み
nabeliwo:テストの話が出たのでそのあたりについて話しますか。この時期から VRT (Visual Regression Test) を試し始めた記憶があります。最初は reg-suit を使って「届出書類」で導入しましたが、設定が非常に大変でしたね。今のSmartHRでは Chromatic がメインになっており、立ち上げが瞬時にできるようになりましたが、当時は導入がかなり大変でした。
koba04:そうですね。
nabeliwo:「届出書類」も最近、Chromatic に移行したんですよね。少し寂しい気持ちもありますね。
koba04:導入にかなり苦労しましたからね……。
nabeliwo:今どきの VRT はやはり Chromatic が主流なのでしょうか?
koba04:Storybook を利用する場合 Chromatic は開発元でもあるので、相性も良いです。もちろん他のオプションもありますが Chromatic は多機能で便利ですね。
nabeliwo:たしかに。テスト周りについても、最初は React を導入してからしばらくテストを書いていませんでしたが、koba04 さんが入ってから徐々にテストを書き始めました。その際、Enzyme を使っていたのが懐かしいですね。テストの状況について覚えていますか?
koba04:おっしゃるように当時はテストの件数は少なかった印象があります。プロダクトの数が多く、スピード重視のフェーズだったので、最低限のテストを書いていたという感じですね。
nabeliwo:その後、2020年から2021年にかけて、「SmartHR」でテストをしっかり整備しようという動きがありました。「SmartHR」のフロントエンドエンジニアが中心となって、msw を導入しつつ Integration テストや E2E テストを整備して、良い感じに揃っていきました。koba04 さんも相談を受けていた記憶がありますが、その時のことを覚えていますか?
koba04:「SmartHR」は他のプロダクトと比べて安定性が求められ、リファクタリングやテストの優先度が高かったですね。より安定したプロダクトにするために、テストをしっかり書いていたと思います。
nabeliwo:その時期から、フロントエンドテストを書く意識が芽生え始めたということでしょうか。
koba04:そうですね。世の中的にも、Testing Library が一般的に使われ始めた時期でした。
nabeliwo:当時は Redux が主流で、社内でも redux-thunk や redux-saga などが使われていましたが、redux-saga を使った処理のテストの書き方が難しくて、koba04 さんに相談したことがありました。generator の next を使って、saga の状態を進めながらテストを書く方法を教えてもらい、とても驚きました。
koba04:やっぱり難しかったですよね。
nabeliwo:非常に難しかったです。今では Redux を使うことは少なくなりましたが、業界全体も同じような感じでしょうか?
koba04:そうですね。Redux 自体は Redux Toolkit などの進化がありますが、全体的に見ると、必要のないプロダクトが多いかなと思います。データフェッチングのためのライブラリもありますし、クライアント側で複雑な状態を持つプロダクトには今でも有効ですが、それ以外のプロダクトでは使われなくなってきています。
nabeliwo:たしかに。以前は何でもかんでもグローバルステートに入れていましたが、今ではそんなにグローバルに持つ必要はなかったのでは、という感じですよね。
この頃、SmartHR UI 以外にも、eslint-config-smarthr や stylelint-config-smarthr、renovate-config など、各種設定ファイルをパッケージ化して公開する動きがありました。その中で、tamatebako というプロジェクトが始まりました。これは SmartHR のプロダクト内で共通で使えるロジックを外部に出そうというものでしたね。
koba04:「たくさんのライブラリが入っているtamatebako」という感じですね。
nabeliwo:その中でも、SmartHR のプロダクトによく出てくる、テーブル内の要素の複数選択、一括選択とか一括解除とかを良い感じにやってくれる機能を共通化できたのは良かったですね。今では多くのプロダクトで使われており、大きな成果だったと思います。また、その時に hooks のテストのやり方も koba04 さんに教えてもらい、非常に助かりました。
Next.js の導入
nabeliwo:次は2022年頃の話に移ります。この時期、フロントエンドエンジニアが21名に増え、新たに「配置シミュレーション」と「SmartHR Plus」という2つのプロダクトが追加されました。この頃から、Next.js が導入され始めました。それまでは Rails API と React SPA の組み合わせが主流でしたが、Next.js を使ったプロダクトが増えていきました。
koba04:そうですね。
nabeliwo:この時期から Next.js の評価が高まり、特にビルド周りやルーティングを任せられるというのが良かったです。それまでは webpack でがんばっていたのが、Next.js のおかげで苦労なく立ち上げられるようになりました。ただ、認証周りの扱いで悩むことが増えました。以前は Rails 側に認証を任せていたのが、Next.js に移行したことで、認証を Next.js で行い、Rails API を叩く時にリクエストヘッダーにアクセストークンを渡す必要が生じました。当時、next-auth を使っていてそれのプロバイダーとして SmartHR Provider を作って共通化するなど、非常に難しかった記憶があります。ここら辺でかなり相談を受けてましたよね?
koba04:そうですね。「配置シミュレーション」が最初に Next.js を導入したプロダクトで、一緒に認証周りや SWR の使用、パフォーマンスなどについても相談しました。
nabeliwo:なるほど。koba04 さんが外部で話していた Next.js の勉強会の発表内容を社内向けに発表してくれたことがありました。それが社内で Next.js が広まるきっかけになり、その後「配置シミュレーション」が他のプロダクトのお手本になった記憶があります。
koba04:そうですね。
新たな技術的挑戦
nabeliwo:その時期、React 18のリリースがあり、Server Component とかが出てきて、SmartHR UI で新しい悩みが生まれましたね。styled-components のような CSS-in-JS が時代に合わなくなってきており、社外の有名なデザインシステムでは CSS modules や Tailwind CSS が使われるようになっていきました。ここから SmartHR UI の大改革が始まるんですが、今では Tailwind CSS への移行が完了しています。
また、同時期にプラットフォーム事業関連で、iframe を使って「SmartHR」に別プロダクトを埋め込むという試みが始まりました。3rd party cookie の問題が大きく、その時も多くの相談をさせてもらいましたね。
koba04:はい、Storage Access APIとか。
nabeliwo:そうそう。最終的には 3rd party cookie をがんばる方向性を諦め、iframe に postMessage で認証に必要な情報を含んだ JWT を渡して、受け取ったプロダクト側でデコードして認証する方法に切り替えました。Storage Access API は、ブラウザごとに挙動が違い、またブラウザも実装途上でどんどん挙動が変わっていって、難しかったです。全然動かなくて koba04 さんに相談するんだけど数週間後に同じコードで動くようになったりして、本当に何が正解かわからない状況でした。
koba04:そうですね。ブラウザごとの違いが大きく、どこに合わせるべきかが非常に難しかったです。
フロントエンドミーティングの見直し
nabeliwo:次は直近の今年や昨年の話に移ります。この頃になると、フロントエンドエンジニアが34名に増え、バックエンドエンジニアもそれ以上のスピードで増えていて、プロダクトエンジニア全体で110名以上に達していたと思います。また、プロダクトが新たに7つ追加されました。もう全てを把握するのが難しくなっていますね。
koba04:そうですね、全ては把握できていません。
nabeliwo:そして、koba04 さんがサイボウズからメルカリに転職され、SmartHRでの週一勤務がなくなりましたよね。それに伴い、Slack ベースでの相談や、たまに同期ミーティングを依頼して相談する形式になりました。
また、フロントエンドミーティングの koba04 さんのコーナー(フロントエンド界隈の最新の情報を共有する場)がなくなったことも大きな変化でした。その際、今後のフロントエンドミーティングのあり方について話し合いましたが、koba04 さん頼みになってしまっていたことがわかりました。koba04 さんの技術情報共有の時間がメインになり、他のメンバーから議題が出づらくなっていたんです。koba04 さん自身もそのように感じていましたか?
koba04:そうですね、議題が出づらくなっている感はありました。カジュアルな内容でハードルを下げようと試みましたが、続かないことも多かったです。なかなか難しいですね。
nabeliwo:その後、みんなでハードルを下げるための話し合いを行い、現在は徐々に改善されていて、議題が続くようになりました。ラフな共有ができるようになったのは良かったことだと思います。その一方で、フロントエンドミーティングでの技術共有がなくなった分、koba04 さんが Slack での週一の技術情報共有をしてくれるようになりましたが、あれは難しい部分もありますよね。
koba04:そうですね。意味がないとまでは言いませんが、議論が広がりにくいと感じています。現在は試行錯誤中ですが、特定の曜日の夜に相談を受け付ける形にしていて、必要に応じて対応するようにしています。ただ、やっぱり相談しづらさはあると思うので、そのハードルを如何に下げていくかというのは今後の課題ですね。
Next.js App Router との向き合い方
nabeliwo:技術的なトピックでは、Next.js のバージョン13から導入された App Router が最近の話題です。これにどう対応するかが課題となっています。多くのプロダクトは Pages Router のまま使っていますが、「採用管理」では App Router を導入しつつ、Client Component 中心で進めています。ここで、Pages Router と App Router の違いについて説明していただいてもいいですか?
koba04:Pages Router は Next.js の初期から採用されているもので、App Router はバージョン13から導入された新しい仕組みです。大きな違いは、App Router が React Server Components という新しい仕組みをフル活用している点です。これにより、サーバーとクライアントの処理がシームレスに統合され、サーバーで行うべき処理はサーバーで、クライアントで行うべき処理はクライアントで行うという分け方が可能になります。ただし、考え方やパラダイムが全く異なるため、導入には難しさがあります。
nabeliwo:最近、社内でフロントエンドの技術課題調査アンケートを行ったところ、App Router への移行について多くの懸念が出てきました。特に SmartHR UI が Server Component で動かないことが問題となっています。Tailwind CSS 化は完了したのですが、Context API の使用など、Client Component 前提の処理が多くあり、まだ Server Component に対応できていません。また最近、ボイラープレートプロジェクトが動いており、新プロダクトの立ち上げがスムーズにできるように基盤を整えているのですが、Next.js でどちらのルーターを使うか、というのはけっこうしっかり議論されていますね。koba04 さんに相談される内容も最近は Next.js 周りが多いですか?
koba04:そうですね、直近もピンポイントに「Next.js で作っているここが遅くて困っていてどうしたら良いか」みたいな相談もありましたね。
nabeliwo:なるほど。パフォーマンス周りの話もここまではあまり話さなかったですが、koba04 さんの参加時から今まで様々な改善をやっていただいてますよね。
koba04:はい。一時期SmartHR UI のビルドサイズを下げることをめちゃくちゃやっていた印象がありますね。
nabeliwo:そうですね。ビルドサイズの削減は非常に助かりました。
SmartHRのフロントエンドの未来と求められるエンジニア像
nabeliwo:さて、これで一通り話し終わったので、まとめに入りたいと思います。今後、SmartHRのフロントエンドをどうしていきたいか、漠然としたテーマですが、話せそうですか?
koba04:そうですね。技術選定に関しては、まず会社としてプロダクトをどうしていきたいかが前提にあって、それを実現するために取り組むものだと考えています。自分のイメージだと、プロダクトをどんどん作っていくスピードが求められる一方で、プラットフォームとしては 3rd party のアプリを動かせるようにするなど、異なる技術的な難しさがあると思います。それぞれの技術的な難しさとか、求められるものは変わってくるので、そこの2軸は今後もあるんだろうなと思って見てはいますね。
nabeliwo:そうですね。今日話したような Next.js 周りの話は界隈でよく聞くようなアプリケーション設計の難しさがあって、またプラットフォーム周りはプラットフォーム特有の技術的な難しさや面白さがあって、その両面があるのはSmartHRのフロントエンドの特徴なので、どちらの方向にも挑戦を続けていきたいですね。
では最後に、どういう人がSmartHRのフロントエンドに合っているかというのを話したいです。弊社のエンジニアの価値観というのがあって「技術志向よりもプロダクト志向だよね」とか、弊社のバリューもあって基本そこにマッチしていることとかがあるんですけど、koba04 さん視点でSmartHRのフロントエンドに合う人ってどんな人ですか?
koba04:入社してくる人を見ていてもプロダクト志向の人が多いというのはとても感じますね。
あとはプロダクトがたくさん生まれてきて、そこにアサインされるフロントエンドエンジニアは少ないので、プロダクトをどういう風に作るかを主体的に考えながら作る経験ができると思います。それが「SmartHR」みたいな大きなプロダクトだと慎重に設計を行う必要がありますが、プロダクトを小さくいっぱい作っていくところでは挑戦しやすいと思います。
これはずっと関わっている中で感じていることなのですが、時期によって相談してくる人ってバラバラなんですよ。常に新しい人がどんどん相談してくれる状況は、いろんな人が技術的な挑戦をしていることの現れでもあると思うので、とても良いことだと思っています。
やっぱりプロダクトを作るというのは大事にしている点なんだろうなっていうのは見ていて感じます。一方でプラットフォーム的な部分でいうと、より技術的に専門性を持った人も必要になってくるところなので、そこの2つに適したエンジニアは今後どちらも必要になってくると思って見ています。
nabeliwo:というところですかね。では、本日はありがとうございました。
koba04:ありがとうございました。