Share
Embed
新規社内システムのモダンなフロントエンド開発について 〜開発の高速化でDXを促進!〜
とらのあなラボTechConferenceVol.2におけるセッション「新規社内システムのモダンなフロントエンド開発について 〜開発の高速化でDXを促進!〜」の登壇資料です。
■イベント情報
https://yumenosora.connpass.com/event/241175/
■今後のイベントについてはこちら
https://yumenosora.connpass.com/
■虎の穴ラボ 採用サイト
https://yumenosora.co.jp/tora-lab/
虎の穴ラボ株式会社
March 25, 2022
Transcript
61 slides
-
新規社内システムのフロントエンド について 〜開発のモダン化で DX を促進!〜 虎の穴ラボ株式会社 古賀広隆 - Copyright (C)
2022 Toranoana Inc. All Rights Reserved. -
所属 虎の穴ラボ株式会社 とらのあな通販コスト削減チーム 主な担当 フロントエンド、サーバサイド 推し 南條愛乃さんです! 自己紹介 Copyright (C)
2022 Toranoana Inc. All Rights Reserved. -
子供の声が入るかも 100% フルリモートワーク で、今日も三重県の自宅から配信して います。 ご了承ください 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022
Toranoana Inc. All Rights Reserved. -
あじぇんだ! 1. とらのあな補充発注システムとは? 2. 各種フレームワーク/ライブラリの選定理由 3. コンポーネント設計の思想 4. StoryBook 駆動の設計/開発
5. 自動テストの導入 6. 最後に 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
SPA/SSG Amazon S3 AWS Cloud Front Backend (Kotlin ) AWS
Cognito EC2 通販システム MySQL DB Aurora Serverless v1 補充担当 補充発注システム 発注 カートに⼊れて発注 補充発注を管理 API ユーザ認証 システム構成イメージ Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Nuxt.js(Vue.js 2 系)を選んだ理由 テンプレート型 SPA/SSG ができる 情報量が豊富、日本語のドキュメントがある テンプレート型は、サーバサイドから移行しやすかった フレームワーク/ライブラリの選定理由 Copyright
(C) 2022 Toranoana Inc. All Rights Reserved. -
UI フレームワーク(Element UI)の選定理由 テーブルを開閉できる ミニマルデザインが選べる マニュアルがわかりやすい(英語) オプションが豊富 内部の CSS 設計が
BEM で CSS を上書きしやすい 主張しすぎない UI デザイン Nuxt.js のインストールオプションにある フレームワーク/ライブラリの選定理由 Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Tailwind CSS(部分的)の選定理由 UI やスタイルの調整は必要になる style や css ファイルを書くのはしんどい CSS ファイルも最小減になる(Just-in-Time
モード) 他の UI フレームワークと組み合わせて使う場合も、適している と判断。 フレームワーク/ライブラリの選定理由 Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
たとえば、よくある通知 UI を作りたい、スタイルシートで書く と、、、 引用元:https://tailwindcss.com/docs/utility-first Tailwind CSSの選定理由 Copyright (C) 2022
Toranoana Inc. All Rights Reserved. -
<div class="chat-notification"> <div class="chat-notification-logo-wrapper"> <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo" />
</div> <div class="chat-notification-content"> <h4 class="chat-notification-title">ChitChat</h4> <p class="chat-notification-message">You have a new message!</p> </div> </div> <style> .chat-notification { display: flex; max-width: 24rem; margin: 0 auto; padding: 1.5rem; border-radius: 0.5rem; background-color: #fff; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); } .chat-notification-logo-wrapper { flex-shrink: 0; } .chat-notification-logo { height: 3rem; width: 3rem; } .chat-notification-content { margin-left: 1.5rem; padding-top: 0.25rem; } .chat-notification-title { color: #1a202c; font-size: 1.25rem; line-height: 1.25; } .chat-notification-message { color: #718096; font-size: 1rem; line-height: 1.5; } </style> Tailwind CSSの選定理由 Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
コード量が多く、開発に時間がかかる 修正するために、理解するのに時間がかかる CSS クラスの名前付けに苦労する HTML/CSS を行き来する必要がある (別ファイルの場合) Tailwind CSSの選定理由 Copyright
(C) 2022 Toranoana Inc. All Rights Reserved. -
Tailwind CSS だとスッキリ <div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg
flex items-center space-x-4" > <div class="shrink-0"> <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo" /> </div> <div> <div class="text-xl font-medium text-black">ChitChat</div> <p class="text-slate-500">You have a new message!</p> </div> </div> Tailwind CSSの選定理由 UI の共通部品は、HTML ごと Vue や React のコンポーネン トで分けます。 “ “ Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Atomic Design の考え方を導入! (単一責任の原則を重視、影響範囲を狭める) 新規社内システムのモダンなフロントエンド開発について 引用元:https://bradfrost.com/blog/post/atomic-web- design/ “ “ Copyright
(C) 2022 Toranoana Inc. All Rights Reserved. -
HTML の構成要素( button 、 img 、 input 、 select 等)
Element UI の構成要素( el-alert 、 el-aside 、 el-card 、 el-table 、 el-table-column 等) store は使わない prop と emit で疎結合(純粋関数の様に)にす る Atomic Design の考え方を導入!(level1 - atoms) Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
前述の atoms と組合わせ el-alert (Element UI)のリスト el-input (Element UI)+ label
atoms +共通処理の組合わせ el-table-column (Element UI) (日付や数量、価格ごと) store は使わない prop と emit で疎結合(純粋関数の様に)にす る Atomic Design の考え方を導入!(level2 - molecules) Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
前述の atoms と molcules の組合わせ 店舗やインショップの階を選ぶ 商品検索条件と結果 ログインフォーム store を使う
バックエンドに必要なデータのみ ロジックと UI の分離 prop と emit で疎結合にする Atomic Design の考え方を導入!(level3 - organisms) Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Atomic Design の Template と Page 今回は、Nuxt.js の page に
organisms を置く方法を取りまし た 手軽さとコスト対費用効果 nuxt.js の page/template と名称が混在する (分かりづらい) Atomic Design の考え方を導入!(その他の要素) Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
StoryBook とは? フロントエンドエンジニア向けのオープンソースのツールです。 1. コンポーネント駆動型の UI を高速に開発する 2. UI コンポーネントとページを分離して、開発できる
3. UI の開発、テスト、およびドキュメント化を合理化できる 公式サイトより StoryBook 駆動の設計/開発 Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Nuxt.js ならかんたんにインストールできます nuxt/storybook を使うと、設定無しで簡単に既存の Nuxt.js プロ ジェクトに導入できます。 公式サイトより さらに、storybook-addon-mock を導入します。
StoryBook 駆動の設計/開発 Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
得られたメリット 1. 実際の動きが誰でも想像しやすい! 2. バックエンドが無くても開発が進められる StoryBook 駆動の設計/開発 Copyright (C) 2022
Toranoana Inc. All Rights Reserved. -
全体の開発工数を抑えられる 設計工数 ↑ 開発工数 ↓↓ 仕様ミスの減少 スケジュール調整の減少 StoryBook 駆動の設計/開発 Copyright
(C) 2022 Toranoana Inc. All Rights Reserved. -
1. 実際の動きが誰でも想像しやすい! StoryBook に Markdown でコンポーネントの仕様を書ける! StoryBook駆動開発の進めかた Copyright (C) 2022
Toranoana Inc. All Rights Reserved. -
コードブロックを書くと、Copy ボタンが追加される <molcules-el-radio-group-radio-list-label v-model=" プロパティの名前" :span="8" :options="[ { key: 7,
label: ' メイドちゃん1' }, { key: 8, label: ' メイドちゃん2' }, ]" > NotAll </molcules-el-radio-group-radio-list-label> サンプルコードのコピーができる Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
1 行書くだけ! ## 属性 <Props of={RadioGroupRadioListLabel} /> コンポーネントの属性一覧が作れる Copyright (C)
2022 Toranoana Inc. All Rights Reserved. -
2. バックエンドが無くても開発が進められる Fetch API のモックを書く! StoryBook駆動開発の進めかた Copyright (C) 2022 Toranoana
Inc. All Rights Reserved. -
mockData: [ { url: 'http://localhost:8080/api/v1/admin-users/user2345%40example.com', method: 'GET', status: 200, response:
{ statusCode: 200, data: { statusCode: 200, id: '[email protected]', displayName: ' 〜課 鈴木一郎', enabled: true, }, }, }, ], Fetch API のモックを書く Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
const userResp = await this.$fetchForBackend( `/api/v1/admin-users/${encodeURIComponent(getters.getLoginId)}`, { method: "GET", mode:
"cors", cache: "no-cache", credentials: "same-origin", headers: { "Content-Type": "application/json", Authorization: `Bearer ${rootGetters["pages/Hoge/getAuthToken"]}`, }, redirect: "follow", referrerPolicy: "no-referrer", } ); FetchAPI(axios)の結果をモックに差し替えらる Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
5. 自動テストについて 1. ビジュアルリグレッションテスト 2. スナップショットによるリグレッションテスト 3. E2E テストを半自動生成 これに加えて、各コンポーネント毎に
Jest のテストケースもあ ります 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
1. ビジュアルリグレッションテストについて プログラムの一部分を変更したことで、 ほかの箇所に不具合が出ていないか視覚的に確認するためのテス ト 今回は、StoryBook と StoryCap を使って 容易に確認できる様にします。
新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
全コンポーネントのスクリーンショットを撮るコマンド $ npx nuxt storybook build $ npx storycap \
--serverCmd "npx http-server storybook-static -p 9001" \ --flat --delay 1000 --viewport iPad \ --viewport "iPad landscape" \ --viewport 1024x970 \ http://localhost:9001 iPad や iPad(横画面)、PC サイズをそれぞれ撮影する 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
まとめ プログラムの一部分の変更で、ほかの構造に変更がないか確認で きる。 ↓ 共通部品やライブラリの変更も気軽にできます。 脆弱性対策 致命的な不具合など 新規社内システムのモダンなフロントエンド開発について Copyright (C)
2022 Toranoana Inc. All Rights Reserved. -
3. E2E テストの半自動生成 Chrome の拡張機能の Headless Recorder を使ってテストケース を半自動生成しました (半なのは、少し修正が必要なため)
唯一の TypeScript を利用したコード 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
カート部分の自動生成コードのサンプル // カートに商品を入れる await page.waitForSelector("#cart-container__box--stock"); await page.screenshot({ path: `${shotsDir}screenshot_${screenShotIndex++}.png`, });
await page.click("#cart-container__box--stock"); // カート画面に遷移する await page.waitForSelector( ".modern-header > .mh-container > .mh-util > .mh-cart > a" ); await page.screenshot({ path: `${shotsDir}screenshot_${screenShotIndex++}.png`, }); await page.click(".modern-header > .mh-container > .mh-util > .mh-cart > a"); 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
自動生成されなかったコードのサンプル // メールアドレスを入力する await page.waitForSelector("#email"); await page.click("#email"); await page.fill("#email", "[email protected]");
// パスワードを入力する await page.waitForSelector("#repass"); await page.click("#repass"); await page.fill("#repass", "xxxxxxx"); // ログインボタンを押す await page.waitForSelector( "div > .container-md > .login-form > .login-form-box:nth-child(1) > .box-style-01" ); await page.click( "div > .container-md > .login-form > .login-form-box:nth-child(1) > .box-style-01" ); 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Appendix: ソースコードや図などの引用元 Element UI 公式 Tailwind CSS 公式 Brad Frost
さん、Atomic Design 考案者のブログ 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved. -
Appendix: TypeScript を採用しなかった理 由 今回は JavaScript を採用しています Vue と相性が悪い JavaScript
をできる人が多い(自分も含め) ライブラリの対応状況がまちまち Vue のテンプレートやストアは型に問題が起きやすかった。 新規社内システムのモダンなフロントエンド開発について Copyright (C) 2022 Toranoana Inc. All Rights Reserved.