$30 off During Our Annual Pro Sale. View Details »

Turborepo Code Generationによる、サイバーエージェントグループのフロントエンド開発の効率化

did0es
September 08, 2023

Turborepo Code Generationによる、サイバーエージェントグループのフロントエンド開発の効率化

JS/TSのプロジェクトで、ビルドシステムやmonorepoの構築に用いられるTurborepoには、Code Generationという機能が存在します。 この機能を活用した、人為的ミスの防止や開発リソースの削減など、実際にサイバーエージェントグループの開発現場で行われている取り組みについてお話します。

イベントURL:https://uit.connpass.com/event/291443/

did0es

September 08, 2023
Tweet

More Decks by did0es

Other Decks in Technology

Transcript

  1. Turborepo Code Generationによる、
    サイバーエージェントグループの
    フロントエンド開発の効率化
    UIT Meetup vol.20『これがぼくらのスタンダード』
    Shuta Hirai

    View Slide

  2. Shuta Hirai
    株式会社サイバーエージェント グループIT推進本部
    CyberAgent group Infrastructure Unit(CIU)
    フロントエンドエンジニア
    Social Accounts
    ・https://github.com/shuta13
    ・https://twitter.com/did0es
    週末は代々木公園でフットサルをして、
    松屋で朝食を食べるのが僕のスタンダードです

    View Slide

  3. 1.CIUのフロントエンドについて
    2.開発における課題
    3.Code Generationによる開発の効率化
    4.CIUにおける活用方法の紹介
    5.所感・まとめ

    View Slide

  4. CIUのフロントエンドに
    ついて

    View Slide

  5. CIU:
    CyberAgent group Infrastructure Unit

    View Slide

  6. CIU:
    サイバーエージェントグループの
    インフラ組織

    View Slide

  7. プライベートクラウドや
    KaaS・IaaSなどのサービス開発、
    全社インフラの支援を行っています

    View Slide

  8. CIUのフロントエンドの主な業務:

    View Slide

  9. CIUのフロントエンドの主な業務:
    サービスの管理画面の開発

    View Slide

  10. CIUの展開するサービス数

    View Slide

  11. 20

    View Slide

  12. CIUのフロントエンドエンジニア数

    View Slide

  13. 2

    View Slide

  14. 開発における課題

    View Slide

  15. ①人手が足りない

    View Slide

  16. サービス数 > 人数
    前述のとおり、サービス数に対して人手が足りていない
    ・20個あるサービス全ての管理画面を作るわけではないが、それでも足りていない
    基本全てのフロントエンドを2人が見る状態
    ・フロントエンドの設計・実装・運用全て2人で担当
    ・さすがに全部は見きれないので、一部(20 - 30%程度)の実装は外注
    ・マネジメント系のタスクも発生する

    View Slide

  17. ②コピペの多用

    View Slide

  18. 管理画面の例

    View Slide

  19. 似たような画面の開発
    社内向け管理画面
    ・基本、新規が出る際は毎回似た構成の画面
    ・提供したいものはあくまでCUIだったもののGUI版
    似ている → 使いまわせる
    ・ドメインは違えど、ほとんどUIは変わらない
    ・UI以外もほとんど変わらない
    ・データ取得、アーキテクチャ、ディレクトリ構成etc…

    View Slide

  20. ファイル数とコピペの問題
    使い回せるが故に、既存からコピペを繰り返す
    ・数枚程度のファイルであれば良いが、数10 〜 100では...
    ・人為的なミスが発生しうる可能性がどんどん上がる
    フロントエンドの構成上、ファイル数が増えがち
    ・Clean Architecture によってデータ取得・更新の流れをわかりやすく
    ・実装の見通しは良いが、その分ファイル数がかさむ
    ・コピペしていては腱鞘炎になりかねない

    View Slide

  21. ③外部のコードの混在

    View Slide

  22. 外注の話
    ・はじめに要件を提示して、成果物を貰う方式
    ・密に連携が取れるわけではない
    ・どうしてもレビューにラグが生じる
    ・開発規約の変更があれば逐一共有する
    ・なるべく揃えて、こちらで巻き取って修正はしないようにしたい
    ・より機械的に、手数少なく共有できると◎

    View Slide

  23. 解決の方針:

    View Slide

  24. 解決の方針:
    開発の工数が少なく事故りにくく、
    外注もしやすい環境を実現する

    View Slide

  25. ノーコードツールを使えば
    良いのでは?

    View Slide

  26. 🙅
    (not for us)

    View Slide

  27. 我々はエンジニア
    技術的挑戦の機会を捨てたくはない
    ・エンジニアがいない組織ではない
    ・自分たちの成長の機会も必要
    仮にノーコードツールを選定したとして
    ・メンテは必要
    ・サービスによって生成物を柔軟に変えられない(ことが多い)
    ・結局コードをいじることになる

    View Slide

  28. プロジェクトのtemplateを作れば
    良いのでは?

    View Slide

  29. 🙆
    (good)

    View Slide

  30. プロジェクトのtemplateを作る場合
    コピペしなくてよくなる
    ・CUI・GUIで画面を生成できる
    ・生成したコードを変更してリリース
    コード自体がExampleの役割を担える
    ・生成したコードを見れば、実装の方針がある程度わかる
    template自体のメンテは必要
    ・依存パッケージの更新、バグ修正など
    ・雛形から作ったサービスの更新も必要

    View Slide

  31. ファイルのtemplateを作れば
    良いのでは?

    View Slide

  32. 🙆🙆
    (great)

    View Slide

  33. View Slide

  34. Code Generationによる
    開発の効率化

    View Slide

  35. ファイルのtemplateを作る場合
    コピペしなくてよくなる・規約で縛れる
    ・プロジェクトのtemplateと同様
    依存パッケージの更新など、重いメンテは必要なくなる
    ・templateの更新だけで済む
    ・影響範囲を絞れる
    ・ダブルメンテ感は減る
    ・書き方が変わった箇所は、grepして修正
    ・(頑張れば)自動化もできる

    View Slide

  36. (再掲)
    解決の方針:
    開発の工数が少なく事故りにくく、
    外注もしやすい環境を実現する

    View Slide

  37. 解決方法の整理
    開発の工数が少ない状態
    → 必要なファイルを既存から人力で探すのではなく、CLIでtemplateから生成
    事故りにくい状態
    → コピペしない templateは常に正しいものにする
    外注しやすい状態
    → CLIの使い方だけ説明すれば、規約通りに実装が進められるようにする

    View Slide

  38. 解決手段 : Code Generation
    コードの自動生成
    ・CLIの引数とtemplateから、コードを吐き出す
    自動生成向けツールの例
    ・Plop: https://plopjs.com
    ・Yoeman: https://yeoman.io
    ・Hygen: https://www.hygen.io

    View Slide

  39. ところで、

    View Slide

  40. ところで、
    CIUではTurborepoを利用しています

    View Slide

  41. なぜTurborepoなのか
    Lernaからの移行
    ・LernaをTurborepo + lerna-liteに置き換えたのがきっかけ
    ・Lernaほど大きなものは我々には不要だった
    ・publishはYarnやlerna-liteで賄える
    Turborepoを選んだ背景
    ・モノレポ管理 + α
    ・ビルドシステムの整備
    ・@turbo/gen

    View Slide

  42. なぜTurborepoなのか
    @turbo/gen
    ・packageやprojectをCLIから作成できる、コード自動生成ツール
    ・基本は、既存のpackageのコピペをCLIで行う形
    ・templateからの生成も可能
    ・JSとHandlebarsで書く
    ・拡張性◎で直感的
    ・InquirerやPlopのAPIを使える

    View Slide

  43. Turborepoって昔からコード生成
    できたっけ...?

    View Slide

  44. Turborepoって昔からコード生成
    できたっけ...?
    → v 1.10(※)から可能になりました

    View Slide

  45. Code Generation(@turbo/gen)
    https://turbo.build/blog/turbo-1-10-0#code-generators

    View Slide

  46. なぜモノレポ管理&ビルドツールに
    Code Generationが入った?

    View Slide

  47. Nxを意識した説
    Nxにもファイル・プロジェクト生成機能がある
    ・https://nx.dev/extending-nx/recipes/local-generators
    ・こちらが先発
    ・JSON SchemaでCLIの引数などを定義できる
    ・ファイル構造を木として操作する
    ・競合としてTurborepoも実装することに(?)
    ・ユーザーからの要望は実際にあった

    View Slide

  48. 実は@turbo/gen、ほぼPlopです

    View Slide

  49. @turbo/gen開発の経緯
    2021/01 : 事の発端(※)
    ・https://twitter.com/jaredpalmer/status/1354886486265573377?s=20
    ・Jared Palmer 氏が、Turborepoに合うGeneratorツールについて調べていた
    ・投票の結果、Turborepoに適したgeneratorにはPlopが選ばれた
    (本人もPlop推しの様子)

    View Slide

  50. @turbo/gen開発の経緯
    同年12月 : package/projectの追加方法についてのDiscussion
    ・https://github.com/vercel/turbo/discussions/243#discussioncomment-1860839
    ・再び Jared Palmer 氏登場
    ・Plopの使用をTurborepoのコミュニティ内でも提案
    ・この後、IssueやDiscussionでちらほらPlopの言及が広がる(※)

    View Slide

  51. @turbo/gen開発の経緯
    翌年4月 : Code Generationに関してのIssue
    ・https://github.com/vercel/turbo/issues/4511
    ・「複製することなく新たなプロジェクトを追加したい」ユーザーからの要望
    ・後にCode Generationを実装する Thomas Knickman 氏による返答
    ・このあたりから設計や実装が始まってそう

    View Slide

  52. かれこれ1年ほどの構想を経て
    2023/05にリリース

    View Slide

  53. @turbo/genがほぼPlopなワケ

    View Slide

  54. @turbo/genがほぼPlopなワケ
    → コアコミッターたちの好み
      (Nxより使いやすさを重視...?)

    View Slide

  55. 実装を見てみると
    よりPlopさを実感できるはずです
    https://github.com/vercel/turbo/tree/
    main/packages/turbo-gen

    View Slide

  56. CIUにおける活用方法の紹介

    View Slide

  57. Docsの内容 + αで行っている
    活用方法についてお話します

    View Slide

  58. ディレクトリ構成
    appやpackageとは分離して、/turbo 以下に集約
    ・/turbo/config.ts : Plopの設定
    ・/turbo/templates/**/*.hbs : Template

    View Slide

  59. Generators
    (前提:Next.js App Routerのプロジェクト)
    ・components : UIコンポーネント
    ・pages : ページ(Page, Layout, Template)
    ・route-handlers : Route Handlers
    ・core-domain : 各種ドメイン(Controller, Entity, Presenter)層
    ・core-schema : ZodによるSchema

    View Slide

  60. Generators
    (前提:Next.js App Routerのプロジェクト)
    ・core-interface : Adapter(ClientとServerとの接続)層のInterface
    ・hooks-adapter : ↑の実装
    ・hooks-usecase : Usecase層
    ・hooks-cache-key-generator : SWRのキャッシュキー
    ・libs-locale : i18n対応用の辞書

    View Slide

  61. Templates
    HandlebarsでGeneratorのTemplateを書く
    ・多くて数十行程度
    ・百行までいくと流石に辛いので
     超えるならTemplate化しない
    ・Templatesの仕様
    ・PromptsのAnswerをReadできる
    ・case-modifiers

    View Slide

  62. Prompts
    所定の位置にファイルを置いて、その中に書く
    ・Promptsの仕様
    ・配列形式でQuestionを記述できる
    ・関数を渡してInquirerのAPIをcallできる
    ・Inquirerのプラグインをそのまま使える
    ・inquirer-fuzzy-pathによる検索→

    View Slide

  63. 動作の様子

    View Slide

  64. Actions
    Promptsと同様に書く
    ・Actionsの仕様
    ・文字列にHandlebarsのSyntaxを使える
    ・配列形式でActionを記述できる
    ・関数を渡して条件分岐等もできる
    ・Templateを差し込む位置を
     Answerによって変更→

    View Slide

  65. 動作の様子

    View Slide

  66. 所感・まとめ

    View Slide

  67. 所感
    👍 スピード感を持って開発を進められるようになった
    ・新規が予定よりも早く、事故なく進行している
    ・外注はこれから
    ・コードの書き方は強制できるので、要件を伝えることに専念できる見込み
    👍 configの書きやすさ
    ・JS分かれば読めて書ける
    ・HandlebarsのSyntaxで文字列の表現力が向上

    View Slide

  68. 所感
    💭 HandlebarsとCLIの動作の遅さ
    ・Handlebarsの見づらさ、CLIの動作の遅さは課題
    ・MD(MDX)だと、より人に優しいかも
    ・CLI部分だけでも脱JSできると速くなりそう
    ・Turborepo側で対応は今のところなさそう

    View Slide

  69. 今後の展望
    Codemod Generatorでファイル更新の半自動化
    ・Codemodを起動するGeneratorで更新に追従できるように
    Turborepoに乗っかり続ける vs Code Generator内製
    ・当面はTurborepoを使い続けそうだが...
    ・Remote Cachingが求めていることに合うか次第
    ・Code Generatorだけ使うなら内製しても良いかも
    ・Inquirerより速いCLI × Handlebars以外のDSL
    ・GoかRustで全部書く

    View Slide

  70. ありがとうございました

    View Slide