Slide 1

Slide 1 text

コンポーネントライブラリとして作 る、ポータブルなデータ分析 
 原田陽紗子


Slide 2

Slide 2 text

原田 陽紗子
 フリーランス 
 フロントエンドエンジニア 
 (STORESとの取引6年目)
 自己紹介
 Hisako Harada
 2

Slide 3

Slide 3 text

Background
 ● デザイン科 
 認知心理学系研究室出身 
 ● 視覚と認知 
 自己紹介
 3

Slide 4

Slide 4 text

↓書籍販売中 ↓ https://tttttahiti.stores.jp PR

Slide 5

Slide 5 text

STORES との関わり 
 ネットショップ・レジ 
 ↓
 データ分析 β(直近1年) 
 自己紹介
 5

Slide 6

Slide 6 text

「新しい」 
 とは?


Slide 7

Slide 7 text

「新しい」とは?
 ① 今までにはなかったさまだ。初めてだ。「 ―・い発 明」「―・い経験」 
 ② 従来のものとは違っている。旧来のやり方を改め ている。「 ―・い企画」「 ―・い考え方」 
 ③ できたばかりだ。できてからあまり日時が過ぎてい ない。「―・い洋服」「 ―・い法律」 
 ④ なまものが取れたばかりで,生き生きとしている。 新鮮だ。「 ―・い野菜」「 ―・い魚」
 7 出典: スーパー大辞林


Slide 8

Slide 8 text

「新しい」とは?
 ① 今までにはなかったさまだ。初めてだ。「 ―・い発 明」「―・い経験」 
 ② 従来のものとは違っている。旧来のやり方を改め ている。「 ―・い企画」「 ―・い考え方」 
 ③ できたばかりだ。できてからあまり日時が過ぎてい ない。「―・い洋服」「 ―・い法律」 
 ④ なまものが取れたばかりで,生き生きとしている。 新鮮だ。「 ―・い野菜」「 ―・い魚」
 8 出典: スーパー大辞林


Slide 9

Slide 9 text

「新しい」とは?
 ① 今までにはなかったさまだ。初めてだ。「 ―・い発 明」「―・い経験」 
 ② 従来のものとは違っている。旧来のやり方を改め ている。「 ―・い企画」「 ―・い考え方」 
 ③ できたばかりだ。できてからあまり日時が過ぎてい ない。「―・い洋服」「 ―・い法律」 
 ④ なまものが取れたばかりで,生き生きとしている。 新鮮だ。「 ―・い野菜」「 ―・い魚」
 9 出典: スーパー大辞林


Slide 10

Slide 10 text

「新しい」とは?
 ① 今までにはなかったさまだ。初めてだ。「 ―・い発 明」「―・い経験」 
 ② 従来のものとは違っている。旧来のやり方を改め ている。「 ―・い企画」「 ―・い考え方」 
 ③ できたばかりだ。できてからあまり日時が過ぎてい ない。「―・い洋服」「 ―・い法律」 
 ④ なまものが取れたばかりで,生き生きとしている。 新鮮だ。「 ―・い野菜」「 ―・い魚」
 10 出典: スーパー大辞林


Slide 11

Slide 11 text

「新しい」とは?
 ① 今までにはなかったさまだ。初めてだ。「 ―・い発 明」「―・い経験」 
 ② 従来のものとは違っている。旧来のやり方を改め ている。「 ―・い企画」「 ―・い考え方」 
 ③ できたばかりだ。できてからあまり日時が過ぎてい ない。「―・い洋服」「 ―・い法律」 
 ④ なまものが取れたばかりで,生き生きとしている。 新鮮だ。「 ―・い野菜」「 ―・い魚」
 11 出典: スーパー大辞林


Slide 12

Slide 12 text

「新しい」とは?
 ① 今までにはなかったさまだ。初めてだ。「 ―・い発 明」「―・い経験」 
 ② 従来のものとは違っている。旧来のやり方を改め ている。「 ―・い企画」「 ―・い考え方」 
 ③ できたばかりだ。できてからあまり日時が過ぎてい ない。「―・い洋服」「 ―・い法律」 
 ④ なまものが取れたばかりで,生き生きとしている。 新鮮だ。「 ―・い野菜」「 ―・い魚」
 12 出典: スーパー大辞林


Slide 13

Slide 13 text

ブリコラージュ 
 「新しい」とは?
 「寄せ集めて自分で作る」 
 「取繕い」 
 設計⇔ブリコラージュ 
 Bricolage
 13

Slide 14

Slide 14 text

巨人の肩の上に立つ矮人 
 「新しい」とは?
 僕らの営みは先人の 
 発見の上にある 
 14

Slide 15

Slide 15 text

M&Aを繰り返しできた 
 「STORES」


Slide 16

Slide 16 text

「STORES」の事情とデータ分析 β
 「今月の売上をまとめて見る」 
 16 1. 各プロダクトごとのオーダーをCSV 形式でダウンロード
 2. Excel でフォーマットを整える
 3. 関数で計算


Slide 17

Slide 17 text

「STORES」の事情とデータ分析 β
 データ分析 β(社内通称 moana)登 場!
 17 各プロダクトの売上やアクセスなどの データを一元集計・GUI上で表現


Slide 18

Slide 18 text

「STORES」の事情とデータ分析 β
 18

Slide 19

Slide 19 text

「STORES」の事情とデータ分析 β
 ページとしてのデータ分析機能 
 ↓
 データ分析の中央集権 
 (セマンティックレイヤー等) 
 19 ※データベースへのアクセスやビジネスロジック等を 内包し提供する仕組みのこと


Slide 20

Slide 20 text

「STORES」の事情とデータ分析 β
 20 データ分析βで表示して いる内容をこっちのダッ シュボードにも
 表示したい
 ネットショップ
 レジ
 予約
 ブランドアプリ


Slide 21

Slide 21 text

コンポーネントベースの UI 開発に混ぜて使える 「ミニ データ分析 β」
  を作りたい! 


Slide 22

Slide 22 text

「ミニデータ分析β」を作りたい
 使い方のイメージ 
 22 ● 任意のパッケージマネージャでイン ストール
 ● jsx や SFC 内で import


Slide 23

Slide 23 text

「ミニデータ分析β」を作りたい
 + 要件
 23 ● STORES プロダクト群のどの環境で も同じ見た目・数字 
 ● API 通信からブラウザでの UI 描画 までを内部で完結 


Slide 24

Slide 24 text

portable moana PJ
 始めましたが ……
 「ミニデータ分析β」を作りたい
 24 絶賛試行錯誤中!

Slide 25

Slide 25 text

根本の課題 
 「クロスフレームワーク」 


Slide 26

Slide 26 text

ネット
 ショップ
 ・
 レジ
 ブランド
 アプリ
 予約
 データ分析β
 
 
 
 
 根本の課題「クロスフレームワーク」 
 26 系
 系


Slide 27

Slide 27 text

根本の課題「クロスフレームワーク」 
 ● React / Vue 2種類を作る 
 ● iframe
 ● Web Components
 27

Slide 28

Slide 28 text

根本の課題「クロスフレームワーク」 
 28 API
 ネットショップ 
 レジ
 ブランドアプリ 
 予約
 データ分析 β
 Request
 Response
 Install
 portable-moana
 React
 portable-moana
 Vue
 Install


Slide 29

Slide 29 text

React / Vue 2種類作る
 根本の課題「クロスフレームワーク」 
 ● Pros
 ○ 各フレームワークごとに適切なものを 提供できる 
 29

Slide 30

Slide 30 text

React / Vue 2種類作る
 根本の課題「クロスフレームワーク」 
 ● Cons
 ○ フレームワーク依存 
 ○ 工数2倍
 ○ 細かい違いが出がち 
 30

Slide 31

Slide 31 text

根本の課題「クロスフレームワーク」 
 31 portable-moana
 widget
 API
 ネットショップ 
 レジ
 ブランドアプリ 
 予約
 データ分析 β
 Request
 Response
 embed
 これ
 一個!


Slide 32

Slide 32 text

iframe
 根本の課題「クロスフレームワーク」 
 ● Pros
 ○ フレームワーク依存ない 
 ○ 枯れてて想像が付きやすい 
 32

Slide 33

Slide 33 text

iframe
 根本の課題「クロスフレームワーク」 
 ● Cons
 ○ 数並べると重くなりそう 
 ○ クロスドメイン間での問題起きそう 
 33

Slide 34

Slide 34 text

根本の課題「クロスフレームワーク」 
 34 portable-moana
 Web Components
 API
 ネットショップ 
 レジ
 ブランドアプリ 
 予約
 データ分析 β
 Request
 Response
 Install
 これ
 一個!


Slide 35

Slide 35 text

Web Components
 根本の課題「クロスフレームワーク」 
 ● Pros
 ○ フレームワーク依存ない 
 ○ もっともらしい Web 標準技術
 35

Slide 36

Slide 36 text

Web Components
 根本の課題「クロスフレームワーク」 
 ● Cons
 ○ 事例が少ない 
 36

Slide 37

Slide 37 text

不確定要素は多いが 
 希望はあるのでは!? 
 根本の課題「クロスフレームワーク」 
 portable-moana
 Web Components
 オレはやるぜ 
 オレはやるぜ 
 そうかやるのか 
 やるならやらねば 


Slide 38

Slide 38 text

調査


Slide 39

Slide 39 text

調査
 39 React のサポート状況に不安が……


Slide 40

Slide 40 text

調査
 40 https://engineering.mercari.com/en/blog/entry/20221207-web-design-system-migr ating-web-components-to-react/ メルカリさんの
 Web Components から React へ
 作り直している事例


Slide 41

Slide 41 text

調査
 ● 使用者とメンテナの同時不足 
 ● SSR むずい
 ● Web Components 自体の技術的制限 
 41

Slide 42

Slide 42 text

(調査時点で不穏だけど) 
 とりあえず

Slide 43

Slide 43 text

Web Components
 表示テスト in
 データ分析 β


Slide 44

Slide 44 text

やってみよう Take.1
 ● SSR できないのを実体験 
 ○ 特にデータ分析 β は App Router なので一 筋縄じゃいかなそう 
 ● ていうか Web Components で今出して るグラフとか再現できんの? 
 44 怪しい
 雲行き


Slide 45

Slide 45 text

やってみよう Take.1 からのどうしよう
 45 Cookpad さんの
 React を Web Components で包んで Rails で使っている事例
 https://techlife.cookpad.com/entry/2022/12/29/090000

Slide 46

Slide 46 text

ブランドアプリ 
 portable-moana
 web-components
 やってみよう Take.1 からのどうしよう
 46 wrap
 portable-moana
 react
 予約
 データ分析 β
 直接
 install
 ネットショップ 
 レジ
 包んだ方をinstall


Slide 47

Slide 47 text

やってみよう Take.1 からのどうしよう
 ● React 版コンポーネントライブラリ 
 ○ こっちが主体 
 ● Web Components 版
 ○ React 版を包んでレンダリングする層 
 47

Slide 48

Slide 48 text

(うまくいくかわからないけど) 
 とりあえず

Slide 49

Slide 49 text

まず React の
 コンポーネントライブラリ 
 を作ります! 


Slide 50

Slide 50 text

まず React のコンポーネントライブラリを作る 
 50 ※β版として一部事業者にのみ提供 
 独立した4個の
 コンポーネントで 
 構成されている 


Slide 51

Slide 51 text

ブランドアプリ 
 portable-moana
 web-components
 まず React のコンポーネントライブラリを作る 
 51 wrap
 portable-moana
 react
 予約
 データ分析 β
 直接
 install
 ネットショップ 
 レジ
 包んだ方をinstall
 成功!


Slide 52

Slide 52 text

次に
 Web Components
 で包みます! 


Slide 53

Slide 53 text

import { createRoot } from "react-dom/client"; import { MoanaSampleButton as SampleButton } from "@heyinc/portable-moana-react"; import sanitize from "@heyinc/portable-moana-react/dist/assets/sanitize.css?inline"; import styles from "@heyinc/portable-moana-react/dist/assets/index.css?inline"; import { LitElement } from "lit"; import { customElement } from "lit/decorators.js"; @customElement("moana-sample-button") export class MoanaSampleButton extends LitElement { connectedCallback() { const domNode = document.createElement("div"); const shadow = this.attachShadow({ mode: "closed" }); shadow.appendChild(domNode); const sanitizeSheet = new CSSStyleSheet(); sanitizeSheet.replaceSync(sanitize); const styleSheet = new CSSStyleSheet(); styleSheet.replaceSync(styles); shadow.adoptedStyleSheets = [sanitizeSheet, styleSheet]; const root = createRoot(domNode); const label = this.getAttribute("label") || "ボタン"; root.render(); } } declare global { interface HTMLElementTagNameMap { "moana-sample-button": MoanaSampleButton; } } 


Slide 54

Slide 54 text

React コンポーネントライブラリを Web Components で包む
 1. shadowDOMを作る
 2. CSS を inline で読み込んで adoptedStyleSheets で shadowDOM にくっつける 
 3. react-dom でレンダリング 
 54

Slide 55

Slide 55 text

React コンポーネントライブラリを Web Components で包む
 55

Slide 56

Slide 56 text

ブランドアプリ 
 portable-moana
 web-components
 React コンポーネントライブラリを Web Components で包む
 56 wrap
 portable-moana
 react
 予約
 データ分析 β
 直接
 install
 ネットショップ 
 レジ
 包んだ方をinstall
 作った!


Slide 57

Slide 57 text

これを
 Nuxt で
 使ってみます! 


Slide 58

Slide 58 text

Web Components ライブラリを Nuxt で使う


Slide 59

Slide 59 text

ブランドアプリ 
 portable-moana
 web-components
 Web Components ライブラリを Nuxt で使う
 59 wrap
 portable-moana
 react
 予約
 データ分析 β
 直接
 install
 ネットショップ 
 レジ
 包んだ方をinstall
 難あり


Slide 60

Slide 60 text

仮説
 Web Components ライブラリを Nuxt で使う
 ● SSR: true のときのみ発生 
 ○ @lit-labs/ssr では HTMLElement はエミュレートさ れてないから 
 60 Nuxt で SSR してるプ ロダクトないし 
 保留でいっか〜 


Slide 61

Slide 61 text

770.00kB?! 


Slide 62

Slide 62 text

巨大な react-dom を bundle したから? 
 クソデカ bundle size


Slide 63

Slide 63 text

クソデカ bundle size
 ● react-dom を bundle せず依存関係にす る
 ○ 使用側で react-dom のバージョン管理 が必要になる 
 ● 軽量な Preact で置き換えられないか? 
 63

Slide 64

Slide 64 text

● Preact
 ○ 各種 React API と 互換性のある軽量 ライブラリ 
 クソデカ bundle size


Slide 65

Slide 65 text

65 react-dom 無
react-dom 込
Preact 込
 47.94kB
 770.00kB
 57.56kB
 92.5% 減!!
 クソデカ bundle size


Slide 66

Slide 66 text

クソデカ bundle size
 66 ブラウザで動かないけど……


Slide 67

Slide 67 text

仮説
 クソデカ bundle size
 ● ビルド済みライブラリ内部の React 部分までは alias が貼れてない 
 ○ 多少なりともハックが必要そう 
 
 67

Slide 68

Slide 68 text

クソデカ bundle size
 ● react-dom を bundle せず依存関係にす る
 ○ 使用側で react-dom のバージョン管理 が必要になる 
 ● 軽量な preact で置き換えられないか? 
 68 難あり
 こっちで行く 


Slide 69

Slide 69 text

これまで
 69 ブラウザで動か ない
 課題
 クロス
 フレーム
 ワーク 課題
 Web Components 
 やろう React と
 相性悪い React 版と Web Components ラップ版
 作ろう
 bundle size 
 がでかすぎる 課題
 Preact でレンダ リングしよ う 課題に次ぐ課題 
 取繕いに次ぐ取繕い 
 課題


Slide 70

Slide 70 text

何を作っているのか? 
 70 ウィジェット?
 コンポーネント?
 マイクロサービス?
 色んな概念の ブリコラージュ かも


Slide 71

Slide 71 text

「新しい」ものを作るには 
 とりあえずやってみる 
 失敗しまくる 
 意外なものが使えるかも? 
 でも目的は見失わないように! 
 71 俺達の戦いは 
 これからだ!!!