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

フロントエンドエコシステムで効率化する組織開発

okmttdhr
November 26, 2022

 フロントエンドエコシステムで効率化する組織開発

jsconf 2022

okmttdhr

November 26, 2022
Tweet

More Decks by okmttdhr

Other Decks in Programming

Transcript

  1. フロントエンドエコシステムで
    効率化する組織開発

    View Slide

  2. 自己紹介
    DMM
    のエンジニア
    スタートアップ => AWS
    受託 =>
    事業会社
    インターネットでの ID: okmttdhr

    View Slide

  3. DMM
    について
    「領域とわず、何でもやる」
    動画配信、英会話、電子書籍、株、3D
    プリント、など
    https://dmm-corp.com/business/

    View Slide

  4. DMM
    プラットフォーム事業本部 (
    以下 PF)
    について
    領域:
    認証認可,
    会員,
    決済,
    不正対策,
    ポイントなど
    エンジニア数: 120
    名以上
    フロントエンドのプロダクト数: 40
    以上
    典型的なリクエスト数: 200~500 RPS

    View Slide

  5. 本日のテーマ
    => DMM
    のプラットフォームで取り組んでいる
    (Web)
    フロントエンド開発のエコシステムについて紹介します

    View Slide

  6. PF
    におけるフロントエンドの課題

    View Slide

  7. PF
    におけるフロントエンドの課題
    1.
    変更容易性の低さ
    2.
    開発効率の悪さ
    3.
    拡張性の低さ

    View Slide

  8. PF
    におけるフロントエンドの課題
    0.
    前提
    DMM
    では従来よりマイクロサービスとして各チーム・アプリケーションが独立して
    開発 (Microservices Architect in DMM Platform - DMM inside)
    フロントエンドも同じように独立・分散して開発されていた

    View Slide

  9. PF
    におけるフロントエンドの課題
    1.
    変更容易性の低さ
    HTML/CSS
    を他部署に委託し PHP
    に組み込み

    フロントエンドに明るくない人が継ぎ足しで保守

    テストなし,
    コーディングスタイルもバラバラ

    変更・リファクタ難易度高
    ※`PHP =
    悪`
    ではなく、私たちの場合はこういう状況になっていたという意図

    View Slide

  10. PF
    におけるフロントエンドの課題
    2.
    開発効率の悪さ
    技術選定など設計力の不足

    エコシステムが存在しない (e.g.
    共通コンポーネント,
    ロギング,
    認証)

    サイロ化

    開発効率の悪化

    View Slide

  11. PF
    におけるフロントエンドの課題
    3.
    拡張性の低さ
    変更容易性の低さ +
    開発効率の悪さ

    拡張性の低さ

    View Slide

  12. PF
    におけるフロントエンドの課題
    3.
    拡張性の低さ
    PF
    では様々なサービスから使われるフロントエンドを提供している
    サービスによって機能を拡張したいケースがある (e.g.
    ログイン画面のテーマを変更,
    サービス固有の決済手段や入力項目を提供する)
    パラメータひとつでUI
    を変化させられるような設計が重要

    View Slide

  13. =>
    フロントエンドに特化したエコシステム
    を構築したい

    View Slide

  14. エコシステムとは?

    View Slide

  15. エコシステムとは?
    特定の集団において、効率的に開発をすすめるためのツール、インフラ、知見、コ
    ミュニティなどの総称

    View Slide

  16. 例. Etsy
    のフロントエンドエコシステム
    参考
    The journey to fast production asset builds with Webpack
    Developing in a Monorepo While Still Using Webpack
    Mobius: Adopting JSX While Prioritizing User Experience
    Etsy’s Journey to TypeScript

    View Slide

  17. 例. Etsy
    のフロントエンドエコシステム
    課題
    大規模なモノレポ環境でのビルド時間
    レガシーなフロントエンドの保守

    View Slide

  18. 例. Etsy
    のフロントエンドエコシステム
    解決策
    モノレポでの webpack
    のビルドを高速化・効率化 (
    自作ミドルウェアなど)
    PHP
    をベースとしたアプリケーションで JSX
    を SSR
    したビューを組み込み
    (Component Islands
    パターンと命名)
    TypeScript
    への移行と社内での教育

    View Slide

  19. Etsy
    にしかない課題
    => Etsy
    のフロントエンドエコシステム

    View Slide

  20. エコシステム (
    プラットフォームエンジニアリング)

    アンチパターン

    View Slide

  21. アンチパターン1:
    なんかイケてる技術を採用する
    流行っている技術を取り入れても組織課題は解決しない (
    こともある)
    あくまで「自分たちが」「なぜ」その技術を使うのかを考える

    View Slide

  22. アンチパターン2:
    他社の真似をする
    真似して解決するなら OSS
    や SaaS
    など既存のソリューションを使おう
    How
    ではなく「プロセス」を真似しよう

    View Slide

  23. アンチパターン3:
    とにかく「エコシステム」をつくる
    プラットフォーム、エコシステムをつくるのはコストが掛かるし、考慮点も多い
    どういう組織体制が理想的かは会社によって異なる
    c.f.
    独りよがりのプラットフォーム / For Whom that Platform Runs - Speaker Deck

    View Slide

  24. PF
    におけるフロントエンドエコシステム

    View Slide

  25. PF
    におけるフロントエンドエコシステム
    1.
    モノレポファースト
    2.
    共通パッケージ
    3.
    デザインシステム Turtle
    DMM
    プラットフォームのフロントエンド開発を支えるエコシステム - DMM inside

    View Slide

  26. 1.
    モノレポファースト

    View Slide

  27. 1.
    モノレポファースト
    エコシステムを中心として開発を進めたい
    =>
    モノレポによる開発を大前提に (
    ツールは Nx
    を使用)

    View Slide

  28. 1.
    モノレポファースト
    技術スタックの統一

    View Slide

  29. 1.
    モノレポファースト
    技術スタックの統一
    モノレポ内のパッケージの恩恵を享受
    社内での知見共有 (
    コーディング規約や典型的な実装など)
    アプリケーションをすぐに開発可能に

    View Slide

  30. 1.
    モノレポファースト
    技術スタックの統一
    アプリケーションをすぐに開発可能に
    コマンドひとつ叩くだけでパッケージを作成 (Nx
    の generator
    を利用)
    モノレポでは、小さいパッケージを如何に簡単に作成できるかが重要
    アプリケーションは1
    時間もかからずに開発可能な状態に
    Measure how long it takes for a developer to share a function between two applications.
    Only when it takes minutes, then folks will do it consistently. https://blog.nrwl.io/how-to-
    develop-react-apps-like-facebook-microsoft-and-google-bdcafcfbc9be
    `
    `

    View Slide

  31. 1.
    モノレポファースト
    CI/CD
    モノレポにアプリケーションをつくると out of the box
    で CI/CD
    が稼働
    テスト,
    ビルド, Lint, Storybook, VRT, Docker
    ビルド,
    デプロイ,
    など
    アプリケーションや開発チームが増えてもスケールする工夫 (
    スケーラブル CI/CD
    with Nx
    モノレポ - Speaker Deck)

    View Slide

  32. 1.
    モノレポファースト
    CI/CD
    Datadog
    での計測 (
    実行時間、失敗率など)
    https://www.datadoghq.com/product/ci-cd-monitoring/

    View Slide

  33. 1.
    モノレポファースト
    CI/CD
    Datadog
    での計測 (
    実行時間、失敗率など)
    ビルド時間をパーセンタイルでマッピングした様子

    View Slide

  34. 1.
    モノレポファースト
    グランドデザイン
    PF
    のフロントエンド (~40)
    をすべて把握
    将来的なすべてのフロントエンドアーキテクチャの理想図をつくる

    もちろん詳細レベルまで絶対的なものではない

    View Slide

  35. 1.
    モノレポファースト
    グランドデザイン
    アプリケーションの分類

    View Slide

  36. 1.
    モノレポファースト
    グランドデザイン
    アプリケーションの分類
    =>
    技術選定などが妥当かを検証

    View Slide

  37. 1.
    モノレポファースト
    グランドデザイン
    アプリケーションの分類
    =>
    どういうチーム体制で運用するか?

    View Slide

  38. 1.
    モノレポファースト
    グランドデザイン
    どういうチーム体制で運用するか?
    =>
    アプリケーションごとにチームを分ける

    View Slide

  39. 1.
    モノレポファースト
    グランドデザイン
    どういうチーム体制で運用するか?
    アプリケーションごとにチームを分ける
    =>
    ビジネスドメインごとにチームを分ける

    View Slide

  40. 1.
    モノレポファースト
    グランドデザイン
    どういうチーム体制で運用するか?
    アプリケーションごとにチームを分ける
    =>
    ビジネスドメインごとにチームを分ける
    モノレポで複数のアプリを凝集度高く配置 +
    ひとつのアプリのように開発

    View Slide

  41. 1.
    モノレポファースト
    グランドデザイン
    アプリのアーキテクチャで長期的に手戻りがすくなくなる
    将来的にこうしたいからいまはMVP
    でこれを実装しよう みたいな判断がしやすくなる
    開発体制までふくめての技術設計ができるようになる
    ` `

    View Slide

  42. 2.
    共通パッケージ

    View Slide

  43. 2.
    共通パッケージ
    モノレポ内外で使えるパッケージ (
    ライブラリ)

    View Slide

  44. 2.
    共通パッケージ
    車輪の再発明を防ぐ
    難しいことは意識せずにアプリケーション開発
    最低限のパッケージを切り出す
    認証
    年齢確認
    ロギング
    トラッキング
    マイクロサービスへの通信
    etc

    View Slide

  45. 2.
    共通パッケージ
    例.
    ロギング
    SSR with Next.js
    の Node.js
    環境のロギング
    各種マイクロサービスへと通信するいわゆる BFF
    としても

    View Slide

  46. 2.
    共通パッケージ
    例.
    ロギング
    Datadog
    上で ログからマイクロサービスへの通信経路を辿れるように
    ログ => Trace, Trace =>
    ログ の双方向
    https://docs.datadoghq.com/tracing/

    View Slide

  47. 2.
    共通パッケージ
    例.
    ロギング
    マイクロサービスで標準化しているログ項目を満たしたい
    標準化することで、複数のマイクロサービス間のログをアーカイブから検索・解析できる。リクエストごとに
    コンテキスト (Node.js
    でいうと async context)
    を保つ必要があり、単純にライブラリ( dd-trace )
    を使うだ
    けでは満たせない
    アクセスログを出力したい
    APM
    でも見られるが、アーカイブしたい都合上アクセスログとして残したい
    ` `

    View Slide

  48. 2.
    共通パッケージ
    例.
    ロギング
    Next.js
    の Custom Server
    を使用
    server.use(loggerWithContext);
    server.all('*', async (req, res) => {
    await handle(req, res);
    logger.accessLog(req, res);
    });

    View Slide

  49. 2.
    共通パッケージ
    例.
    ロギング
    使うだけで最低限の可視性を担保
    アプリケーション開発者は logger
    の仕組みを意識する必要は無い
    import { logger } from '@dmm-com/pf-node-logger';
    export const getServerSideProps = () => {
    try {
    api.get('/api');
    ...
    } catch (e) {
    logger.error(e);
    ...
    }
    }

    View Slide

  50. 2.
    共通パッケージ
    例.
    ロギング
    私たちのユースケースにおいて技術スタックが適切かを事前に検討
    e.g. Next.js
    Custom Server
    を使うかどうか
    Static Optimization
    を使うかどうか
    Next.js
    以外の選択肢はありえるのか (Remix
    など)
    ` `
    ` `

    View Slide

  51. 3.
    デザインシステム Turtle

    View Slide

  52. 3.
    デザインシステム Turtle
    「デザイン原則」「デザイントークン」「コンポーネントライブラリ」で構成
    広いサービスに使われることを考慮 (
    トークンの設計、コンポーネントの IF
    など)

    View Slide

  53. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    レスポンシブデザインにおける課題
    PC
    向けのフォントサイズが SP
    では大きすぎる
    複数のブレークポイントでデザインをつくるのはコストがかかる
    その上でもすべてのデバイスサイズで最適な見え方になるとは限らない

    View Slide

  54. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    解決策
    タイポグラフィもレスポンシブに
    デザインシステムにおけるタイポグラフィーの試行錯誤 - DMM inside (
    少し内容が
    古いです)
    c.f. https://web.dev/learn/design/typography/
    ※ 22/11
    現在、実験的な施策

    View Slide

  55. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    /**
    * @param scale
    各トークン (heading1, body1
    など)
    の基準となる大きさ。単位は rem

    */
    const responsiveFontSize = (scale) => {
    return {
    /**
    * xl
    で拡大し始める
    */
    fontSize: `calc( ${scale} * clamp(1rem, 1vw, 1.625rem))`,
    /**
    * sm, md, lg
    では拡大も縮小もしない
    */
    [mediaQueries.lg]: {
    fontSize: `${scale}rem`,
    },
    /**
    * xs
    から縮小し始める
    */
    [mediaQueries.xs]: {
    fontSize: `calc( ${scale} * clamp(1rem / 1.125, 0.55rem + 1vw, 1rem))`,
    },
    };

    View Slide

  56. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    /**
    * sm, md, lg
    では拡大も縮小もしない
    */
    [mediaQueries.lg]: {
    fontSize: `${scale}rem`,
    },
    /**
    * @param scale
    各トークン (heading1, body1
    など)
    の基準となる大きさ。単位は rem

    */
    const responsiveFontSize = (scale) => {
    return {
    /**
    * xl
    で拡大し始める
    */
    fontSize: `calc( ${scale} * clamp(1rem, 1vw, 1.625rem))`,
    /**
    * xs
    から縮小し始める
    */
    [mediaQueries.xs]: {
    fontSize: `calc( ${scale} * clamp(1rem / 1.125, 0.55rem + 1vw, 1rem))`,
    },
    };

    View Slide

  57. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    /**
    * xl
    で拡大し始める
    */
    fontSize: `calc( ${scale} * clamp(1rem, 1vw, 1.625rem))`,
    /**
    * xs
    から縮小し始める
    */
    [mediaQueries.xs]: {
    fontSize: `calc( ${scale} * clamp(1rem / 1.125, 0.55rem + 1vw, 1rem))`,
    },
    /**
    * @param scale
    各トークン (heading1, body1
    など)
    の基準となる大きさ。単位は rem

    */
    const responsiveFontSize = (scale) => {
    return {
    /**
    * sm, md, lg
    では拡大も縮小もしない
    */
    [mediaQueries.lg]: {
    fontSize: `${scale}rem`,
    },
    };

    View Slide

  58. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    /**
    * @param scale
    各トークン (heading1, body1
    など)
    の基準となる大きさ。単位は rem

    */
    const responsiveFontSize = (scale) => {
    return {
    /**
    * xl
    で拡大し始める
    */
    fontSize: `calc( ${scale} * clamp(1rem, 1vw, 1.625rem))`,
    /**
    * sm, md, lg
    では拡大も縮小もしない
    */
    [mediaQueries.lg]: {
    fontSize: `${scale}rem`,
    },
    /**
    * xs
    から縮小し始める
    */
    [mediaQueries.xs]: {
    fontSize: `calc( ${scale} * clamp(1rem / 1.125, 0.55rem + 1vw, 1rem))`,
    },
    };

    View Slide

  59. 3.
    デザインシステム Turtle
    例.
    レスポンシブタイポグラフィ
    アプリケーション開発者はトークンを使うだけ
    const foo = (theme: TurtleTheme) => {
    return css(theme.typography.body1)
    };

    View Slide

  60. PF
    におけるフロントエンドエコシステムまとめ
    1.
    モノレポファースト
    2.
    共通パッケージ
    3.
    デザインシステム Turtle
    変更容易性,
    開発効率,
    拡張性 を底上げしていく⭐️
    DMM
    プラットフォームのフロントエンド開発を支えるエコシステム - DMM inside

    View Slide

  61. Q.
    エコシステムによって「楽ができた」と感じます
    か?

    View Slide

  62. 今後チャレンジングな課題
    破壊的変更をすべてのアプリケーションに適応する運用
    例えば、モノレポ上に50
    アプリが乗ったとして、パッケージの破壊的変更をすべてに適応するにはどうする
    か?単純に手で直していくのではスケールしない。
    ビルド、デプロイの高速化
    高速化はその時々で行っているものの、アプリケーションやコードが増えるたびにじわじわ増えてくる。より
    スケールする仕組みが必要になってくる。
    巨大なフロントエンドを分離
    PHP
    モノリスからより小さな機能を提供するアプリケーションに移行し、拡張性を担保できる状態にする。

    View Slide

  63. 今後チャレンジングな課題
    =>
    スケーラビリティ

    View Slide

  64. ご清聴いただきありがとうございました。

    View Slide