かみお氏の自己紹介

かみお氏:「レガシーフロントエンドをリプレイスしたら開発生産性が向上しました」というタイトルでお話をします。よろしくお願いします。

まず自己紹介を簡単にさせてください。2021年1月にスタメンに入社して、主にフロントエンドを担当している「かみお」です。現在は、今回お話しするNext.jsへのリプレイスのプロジェクトに参加中です。今回初登壇なのでお手柔らかにお願いします。

今日は、リプレイス後のフロントエンドに関することを中心にお話しします。移行時のインフラに関する内容などはテックブログにあるので、そちらを見てもらえたらなと思います。

(スライドを示して)アジェンダはこのようになっています。本日は3の「開発生産性を向上させたこと」を中心にお話ししたいと思っています。

会社・プロダクト紹介

まずは「会社/プロダクト紹介」です。株式会社スタメンは2016年創業で、「一人でも多くの人に、感動を届け、幸せを広める。」という経営理念の下、エンゲージメントプラットフォームの「TUNAG」の開発をしています。

TUNAGの主要機能としては、日報などの社内の情報が集まるタイムラインやビジネスチャット、申請や承認などの社内の手続きに活用できるワークフローなど、ほかにもまだまだ多くの機能があります。

こういったさまざまな機能を通して、企業のエンゲージメント向上から業務DXまでをワンストップで実現する、ALL-in-One ProductがTUNAGになります。

このようにさまざまな機能があるのは、TUNAGが今まで新規の機能開発に力を入れてきたからです。ただその一方で、技術的な負債の解消や技術的なアップデートに注力することがあまりできていませんでした。

そのような状況の中で、今後のサービス拡大やエンゲージメント、組織の拡大を考えた時に、その負債を解消せずに開発し続けることは難しいという判断になり、それを改善をするための1つのプロジェクトとして、フロントエンドのリプレイスプロジェクトがスタートしました。

リプレイス前の課題

そういった背景でスタートしたリプレイスのプロジェクトですが、リプレイス前の課題は次のようなものがありました。

1つ目は複数の開発環境でキャッチアップのコストが高いという課題です。TUNAGのフロントエンドは開発環境が複数あって、1つ目がRailsのERBとjQuery。2つ目がReactとJavaScriptで、プロジェクトスタート時はNode.jsの8(node v8)でした。3つ目がReact、TypeScript、node v12です。

2つ目と3つ目のReactは、RailsのReact-Railsというライブラリを使って、RailsのViewの一部にReactを埋め込んで表示することをしています。なので、同じページでもReactで実装されている機能もあったり、Railsで実装されていたりというように、キャッチアップのコストがすごく高かったです。

そのため、長く在籍している人でも「ここってReactだったんだ」「ここってRailsだったんだ」みたいな会話が出てくるぐらいでした。そのような理由で、キャッチアップのコストがとても高いという課題がありました。

そのほかにも、OpenAPIがなくてコミュニケーションコストが高かったり、ディレクトリ構成に統一感がなかったり、テストがほとんどなかったりなどの課題がありました。

このような課題があったんですが、現在進行中のリプレイスプロジェクトでは、かなり開発体験が良く、開発生産性が高い状態だと感じています。今回はそれらの開発生産性を向上させたと感じたことを5つ紹介したいなと思います。

aspidaとMSWを使ったスキーマ駆動開発

(スライドを示して)今回話すのはこちらの5つです。

1つ目はaspidaとMSWを使ったスキーマ駆動開発です。スキーマ駆動開発を助けてくれたのは、TUNAGの場合だとaspidaとMSWでした。

aspidaはOpenAPIから型安全なAPIクライアントとレスポンスの型を自動生成してくれるライブラリで、MSWはAPIのリクエストをインターセプトしてモックを返してくれるライブラリです。

(スライドを示して)aspidaを使わなかった場合というよりは、OpenAPIから自動生成してくれるライブラリのようなものを使わなかった場合、例えばこんな感じに書くのかなと思います。

ただ、これはいくつかミスをする可能性があって。例えばURLは「users」と直接書いているのでtypoする可能性もあるし、レスポンスの型が違ったり、paramsを間違えてしまったりするような可能性もあると思います。

次にaspidaを使った場合ですが、型安全なAPIクライアントを作成してくれるので、URLのtypoもないし、レスポンスの型も指定しなくてよくて。クエリとかもtypoがあったり、型が異なれば型エラーがあったりします。

ということで、スキーマ駆動開発を採用することで、今まで自力で書いていたものが自動化できて、OpenAPIさえあればAPIの開発を待たずにフロントの実装を完了させることができるようになって、開発生産性を向上をすることができました。

featuresディレクトリを使った構成

次にfeaturesディレクトリです。featuresディレクトリは機能ごとにフォルダを分けて、その機能に必要なものをまとめて管理するというような構成です。(スライドを示して)この例でいうと、Todoで必要なhooksとかコンポーネントなどのファイルを格納しています。

APIはaspidaによる自動生成をしているので、ここには入っていないです。

このような構成にして良かったことは、スコープがわかりやすいので、影響範囲がわかりやすいということです。

また、現在リプレイスはページごとに行っているんですが、ページは複数の機能によって成り立っているので複数のfeatureが表示されていますが、それぞれがお互いに影響を与えないので、複数人、今だとチーム4人で同じページを開発していてもコンフリクトとかはなく、スムーズに進められているのが良かったなと思っています。

Hygenを使ったテンプレート化

次にHygenを使ったテンプレート化です。HygenはCLI上で雛形を生成できるものです。(スライドを示して)左側のコードは実際の雛型です。nameのところは対話形式で入力した内容が入っています。ほかにもいろいろな対話形式でできますが、今回その紹介はちょっと割愛します。

また、右側の画像はHygenで自動生成したものですが、ファイルの中だけではなくて、ディレクトリごと作成できるのでとても便利です。また、複数のファイルを1セットとして作成することも可能です。

(スライドを示して)一部割愛していますが、srcの配下のディレクトリがこんな感じになっていて、赤字の部分はHygenで生成することができます。先ほどもお話ししましたが、srcのすぐ下にあるapisは自動生成しているので、それを考えると、ほとんどのものがイチから実装するものがないような状態にできています。

この運用をしていて良かったことは、ふだんフロントエンドを開発しないメンバーとか新しいメンバーが開発をしても、ディレクトリの構成などをきれいに保ちやすくなったというところです。Hygenを使い始めた頃は、毎回同じようなコードを書くことを「自動生成できることによる工数の削減というのがメリット」だと考えていたんですが、今は構成をテンプレート化できるところのほうが大きいメリットだなと感じています。

そのほかにもStorybookのファイルとかも生成しているので、簡単に引数を追加するだけで、ほぼなにも考えずにStorybookに載せられるようなところもすごく良かったなと思っています。

コード規約でなくlintで修正を行う

4つ目は「コード規約でなくlintで修正」です。コード規約は守るのがけっこう難しいと思っていたので、今は作成していません。その代わり「ESLint」とかのルールでできるだけ縛るようにしています。

ただ、縛りが強すぎてもかえって開発生産性を落としてしまうので、レビューとかで話題になった時にメンバーで話して、その後にルールを追加するようにしています。

良かったこととしては、コードの統一感が出たのはもちろんですが、レビューの時間の短縮にもつながっているのかなと思います。開発者の好みによって書き方が異なるっていうようなこともあると思うんですが、そういったものは、ある程度ルール化してしまうのがいいのかなと思っています。

READMEやWikiの充実

5つ目は、READMEやWikiの充実というところで、環境構築方法とか開発の流れとか、いろいろ書いています。こういったドキュメントを多く残しています。

また、月に1回チームのメンバーでドキュメントを読む時間を作っていて、そこで更新漏れとか、「もっとこうしたほうがいいよね」みたいなところを話してアップデートをするようにしています。また、新しいメンバーが入ってきた時とかにも同じようにアップデートも行っています。

これによって良かったことは、新しいメンバーがスムーズに開発を始められるようになったことです。TUNAGでは2023年8月と9月に、エンジニアの学生の短期のインターンをやりました。2週間という短い期間で、1ページ丸々リプレイスをしてリリースしてくれる方もたくさんいました。

それはその方の技術力が高かったというのもあると思いますが、こういうドキュメントの整備とかで、すぐに開発を始められる状況を作れていたのがすごい大きかったなと思います。また、選定した技術の背景とかがあることで、納得感とかライブラリの移行の時にも役に立つのではないかなと思っています。

以上が開発生産性を向上させたこと5選でした。

設計・選定したものをどのように継続していくか考えることが大事

最後に、自分がこのプロジェクトを通して学んだことを話してまとめとさせてください。このプロジェクトを通して技術的なことはたくさん学べましたが、大きかったのは、どうやって最初に設計・選定したものを継続していくかを考えることがすごく大事だなと思っています。プロジェクトは2023年1月に始まったばっかりなのでまだ10ヶ月とかなんですが、そう感じています。

例えば、プロジェクトの初めにStorybookを導入したとしても、その後、人によって載せたり載せなかったりみたいなことがあるとカタログとしても不完全だし、後でUIテストとかをやろうと思っても載っていないものがあったりするので、効果がすごく減ってしまうと思います。

Storybookってすごいいいものだなとは思いますが、そういうのを継続していくルールみたいなのができていないと、せっかくいいものがもったいないと感じています。そういう状態だと、最悪ライブラリを導入したこと自体がマイナスになってしまうこともあるのかなと思います。

そういったことを避けるために、一部自動化をさせることで、手間を減らしたり、テンプレート化することで、考えなくてもその設計を自然に守れるようにしたりとか、ドキュメントを整備して、少しでも楽に実装してもらえるようにしたりがとても重要で。それが開発生産性の向上につながると思うので、今回話した内容が、みなさんの開発生産性の向上につながれば、お役に立てればいいなと思います。

ご清聴ありがとうございました。