Slide 1

Slide 1 text

デザインシステムを後から導入する前提で作った 変更に強いNuxt3 プロジェクト

Slide 2

Slide 2 text

自己紹介

Slide 3

Slide 3 text

CV CV 名前: みゅーとん 趣味: VR, エレクトーン 仕事: フロントエンド開発, 基盤開発, テックリード sns: twitter .. @_mew_ton 私について

Slide 4

Slide 4 text

CV CV 「ウェルネス産業を、新次元へ。」 月額制サブスク店舗のための次世代 顧客管理・予約・決済システム 「hacomono」を提供 フィットネスクラブ・24時間ジム・ゴルフ・ダンススタジオ等の 月額制店舗に適した会員管理・予約・キャッシュレス決済システム 2019年3月にリリースし、これまでに1,400店舗以上が導入 コロナ禍により、店舗は人との接触を削減する必要があり、 導入件数は前年比10倍以上のペースで増えている hacomono について

Slide 5

Slide 5 text

CV CV 今回のテーマ

Slide 6

Slide 6 text

CV CV デザインシステムを後から導入する前提で作った 変更に強いNuxt3 プロジェクト

Slide 7

Slide 7 text

CV CV デザインシステムを後から導入する前提で作った 変更に強いNuxt3 プロジェクト

Slide 8

Slide 8 text

変更に強い とは

Slide 9

Slide 9 text

CV CV あとから Design System に乗り換えるなら Atomic Design を意識して実装してあれば 変更点は少なくて済む (?) 極論

Slide 10

Slide 10 text

CV CV 開発メンバー全員に Atomic Design を意識してもらうのは 結構難しい しかし、そうもいかない

Slide 11

Slide 11 text

CV CV 1. Atomic Design のような構成を機械的に維持できる 2. 影響範囲がわかる状態 “変更に強い” means

Slide 12

Slide 12 text

CV CV やったことを 順番に解説していきます

Slide 13

Slide 13 text

CV CV - Nuxt v3.0.0-rc.6 - Vue v3.2.37 前提

Slide 14

Slide 14 text

やらかさない Atomic Design

Slide 15

Slide 15 text

CV CV パーツ単位でUIデザインを設計/実装する手法 Atomic Design ?

Slide 16

Slide 16 text

CV CV 見たことある図 出典: atomic design, https://bradfrost.com/blog/post/atomic-web-design/

Slide 17

Slide 17 text

CV CV Nuxt3 の構成だと・・ 出典: atomic design, https://bradfrost.com/blog/post/atomic-web-design/ src/pages 配下に作っておけば良さそう (src/components/pages があっても良) src/components/* に全部置く・・?

Slide 18

Slide 18 text

CV CV 素直な導入はできない

Slide 19

Slide 19 text

CV CV やりがちな失敗 ● organism ? molecule ? 区別がつかない ● molecule が fetch してるのを “コードレビューで” 防ぐの辛い ● 結局 src/components/* 以下が汎用 / 非汎用 が混在してカオスになる

Slide 20

Slide 20 text

CV CV 実装向けの Atomic Design の拡張 Atoms, Molecules (Vue3 components) Atoms, Molecules を区別しない Nuxt3 とは違うプロジェクトで Vue3 Component として実装 将来的に Design System に置き換えていく Organisms (Nuxt3 src/components/*) Domain, Nuxt Contextに 紐付くなら粒度に限らず Organisms 粒度に限らず fetch 等して良い Nuxt3の src/components に配置

Slide 21

Slide 21 text

CV CV プロジェクト開始時点のフォルダ構造

Slide 22

Slide 22 text

CV CV 構成のメリット Atoms, Molecules (Vue3 components) composable が auto-import されない Domain データの interface が Nuxt 側にあり 参照できない 汎用的な作りがほぼ強制される Organisms (Nuxt3 src/components/*) composable を利用できる 汎用コンポーネントがほぼ作られない DesignSystem を import して使う体制に近い

Slide 23

Slide 23 text

Design System もどきを作る

Slide 24

Slide 24 text

CV CV おさらい Atoms, Molecules (Vue3 components) Atoms, Molecules を区別しない Nuxt3 とは違うプロジェクトで Vue3 Component として実装 将来的に Design System に置き換えていく Organisms (Nuxt3 src/components/*) Domain, Nuxt Context (vue-routerなど)に 紐付くなら粒度に限らず Organisms 粒度に限らず fetch 等して良い Nuxt3の src/components に配置

Slide 25

Slide 25 text

CV CV アウトプット Atoms, Molecules $ start-storybook…………………… Organisms $ nuxt dev……..………………………..

Slide 26

Slide 26 text

CV CV ● Storybook に表示されるものを正とする ● (Storybook 6.4以上) play function もなるべく実装 ● 必要ならドキュメントも作る ● Chromatic を利用して Visual Regression Test を実施 vue3 component 実装ルール

Slide 27

Slide 27 text

CV CV

Slide 28

Slide 28 text

CV CV

Slide 29

Slide 29 text

CV CV Chromatic ? Chromaticは、UIフィードバックの収集、ビジュアルテスト、ドキュメンテーションを自動化することで、 開発者は少ないマニュアル作業で迅速にイテレーションを行うことができます。 出典: chromatic, https://www.chromatic.com “ ” CI/CD で Storybook を使った Visual Regression Test ができる

Slide 30

Slide 30 text

CV CV

Slide 31

Slide 31 text

server/api を必ず作る

Slide 32

Slide 32 text

CV CV server/api ? Server Routes server/api 配下にファイルを配置し、 API エンドポイントを定義できる 出典: Nuxt3 guide, https://v3.nuxtjs.org/guide/features/server-routes/

Slide 33

Slide 33 text

CV CV ● すべての API コールは server/api の処理を経由すること (※) ● server/api では、取得データを ViewModel に変換して返す fetch 処理実装時のルール ※ Sentry, DataDog などは除く

Slide 34

Slide 34 text

CV CV ● 取得データ → ViewModel 変換処理が client の js に含まれない ● useFetch が型安全 ● useFetch, useAsyncData によるキャッシュフローが実装しやすくなる ● ViewModel だけを考慮する mock サーバが作れる server/api を必ず実装する メリット

Slide 35

Slide 35 text

CV CV Mock サーバの作り方

Slide 36

Slide 36 text

CV CV server/api の モックサーバの作り方 1

Slide 37

Slide 37 text

CV CV server/api の モックサーバの作り方 2 import type { Health } from '~/lib/models/health' declare const url: string export default defineEventHandler( async (event) => { // 外部から値を取ってきて const result = await $fetch(url) // ゴニョゴニョいじって返す return toHealth(result) } ) function toHealth(response: unknown): Health { // … } src/server/api/health.get.ts test/server/api/health.get.ts import type { Health } from '~/lib/models/health' import mock from './health.json' export default defineEventHandler(() => { // モックデータの JSON を返すだけ return mock })

Slide 38

Slide 38 text

CV CV nuxt.config.ts に以下を追記 .. server/api の モックサーバの作り方 3 // おまじない hooks: { 'nitro:config': (config: NitroConfig) => { if (isTest()) { const testServer = resolve(__dirname, './test/server') config.srcDir = testServer config.scanDirs = [testServer] } } }

Slide 39

Slide 39 text

最低限の E2E テストを実装

Slide 40

Slide 40 text

CV CV Node.js 上からブラウザを操作するライブラリ E2Eテストによく使う Visual Regression Test が可能 Playwright

Slide 41

Slide 41 text

CV CV 実装するテストコード import { test, expect } from '@playwright/test' test.describe('/login', () => { test('画面表示', async ({ page }) => { // ページを表示 await page.goto('./login') // 描画完了を待つ await page.waitForLoadState('domcontentloaded') // 描画結果をスナップショットテスト await expect(page).toHaveScreenshot() // おわり }) }) test.afterEach(async ({ page }) => { await page.close() })

Slide 42

Slide 42 text

CV CV ● モックサーバモードで Nuxt を立ち上げる ● 全ページについて、ページにアクセスして Snapshot するだけをテスト ● それ以外のテストは、やりたければやる E2Eテスト実装のルール

Slide 43

Slide 43 text

CV CV CV

Slide 44

Slide 44 text

CV CV CV

Slide 45

Slide 45 text

まとめ

Slide 46

Slide 46 text

CV CV 1. Atomic Design の構成を機械的に維持できる 2. 影響範囲がわかる状態 “変更に強い” means (おさらい)

Slide 47

Slide 47 text

CV CV 1. Atomic Design の構成を機械的に維持できる Atoms, Molecules は Nuxt3 の src/components/* に実装しない Vue3 プロジェクトに切り出して作る まとめ

Slide 48

Slide 48 text

CV CV 2. 影響範囲がわかる状態 Atoms/Molecules を Storybook, Chromatic で VRT Pages を Playwright で VRT Playwright でのテストの実装を容易にするには server/api の実装とモックサーバ化があると楽 まとめ

Slide 49

Slide 49 text

CV CV この構成にした他のメリット ● テスト実装工数が少なめ ● OpenAPI → GraphQL に変更する予定としても変更に強い ● フロントエンド初心者には比較的易しめ ○ Vue, Nuxt の難易度の低さも相まって ○ Storybook のお作法を覚えてね という辛さはある まとめ

Slide 50

Slide 50 text

CV CV CV 終