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

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

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

弊社では将来的に弊社独自のデザインシステムの設計の後、既存のプロジェクトをすべて置き換えていく予定となっています。
私は、直近立ち上がった新規プロジェクトにて、将来的にデザインシステムに置き換わることが確実であることを前提として、変化に強く、テストコードによる品質を担保できるNuxt3プロジェクト開発基盤を作りましたので、本セッションにて共有できればと思います。

hacomono Inc.

January 30, 2023
Tweet

More Decks by hacomono Inc.

Other Decks in Programming

Transcript

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

    View Slide

  2. 自己紹介

    View Slide

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

    View Slide

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

    View Slide

  5. CV
    CV
    今回のテーマ

    View Slide

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

    View Slide

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

    View Slide

  8. 変更に強い とは

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  14. やらかさない Atomic Design

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 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 に配置

    View Slide

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

    View Slide

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

    View Slide

  23. Design System もどきを作る

    View Slide

  24. 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 に配置

    View Slide

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

    View Slide

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

    View Slide

  27. CV
    CV

    View Slide

  28. CV
    CV

    View Slide

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


    CI/CD で Storybook を使った Visual Regression Test ができる

    View Slide

  30. CV
    CV

    View Slide

  31. server/api を必ず作る

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  35. CV
    CV
    Mock サーバの作り方

    View Slide

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

    View Slide

  37. 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
    })

    View Slide

  38. 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]
    }
    }
    }

    View Slide

  39. 最低限の E2E テストを実装

    View Slide

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

    View Slide

  41. 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()
    })

    View Slide

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

    View Slide

  43. CV
    CV
    CV

    View Slide

  44. CV
    CV
    CV

    View Slide

  45. まとめ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  50. CV
    CV
    CV

    View Slide