Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

PF におけるフロントエンドの課題 1. 変更容易性の低さ HTML/CSS を他部署に委託し PHP に組み込み ↓ フロントエンドに明るくない人が継ぎ足しで保守 ↓ テストなし, コーディングスタイルもバラバラ ↓ 変更・リファクタ難易度高 ※`PHP = 悪` ではなく、私たちの場合はこういう状況になっていたという意図

Slide 10

Slide 10 text

PF におけるフロントエンドの課題 2. 開発効率の悪さ 技術選定など設計力の不足 ↓ エコシステムが存在しない (e.g. 共通コンポーネント, ロギング, 認証) ↓ サイロ化 ↓ 開発効率の悪化

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

エコシステムとは?

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

例. 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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

エコシステム ( プラットフォームエンジニアリング) の アンチパターン

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

1. モノレポファースト

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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 ` `

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

1. モノレポファースト グランドデザイン PF のフロントエンド (~40) をすべて把握 将来的なすべてのフロントエンドアーキテクチャの理想図をつくる ※ もちろん詳細レベルまで絶対的なものではない

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

2. 共通パッケージ

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

3. デザインシステム Turtle

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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))`, }, };

Slide 56

Slide 56 text

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))`, }, };

Slide 57

Slide 57 text

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`, }, };

Slide 58

Slide 58 text

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))`, }, };

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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