Slide 1

Slide 1 text

フロントエンド 最強ディレクトリ構成 株式会社ラクス 勤怠開発2課 北嶋初音

Slide 2

Slide 2 text

index ● 発表経緯 ● 開発フェーズによる特徴 ● 利用技術 ● ディレクトリ構成見直し ● まとめ

Slide 3

Slide 3 text

発表経緯 ● 楽楽勤怠のリリースから約2年 ● 開発も運用フェーズへと移行しつつある ● ディレクトリ設計の見直しもたびたび必要があった ● 設計方針がある程度固まってきたので共有 ● 経緯や具体的な移行内容をまとめておく

Slide 4

Slide 4 text

開発フェーズによる特徴 初期 開発スピード重視 ● 共通化 ○ 1箇所直したらで全部直って欲 しい ● 機能要件が満たせればOK 現在 品質(保守性)重視 ● 責務の分割 ○ デグレを防止したい ○ 修正の影響箇所を絞りたい ● テストコードも書きたい

Slide 5

Slide 5 text

利用技術 ● Vue.js(2系) ● Vuex ● TypeScript ● Axios ● Jest ● Testing Library ● Storybook ※今回分かっておけば良い部分のみ記載

Slide 6

Slide 6 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/

Slide 7

Slide 7 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ → 複数画面で利用される 共通コンポーネント(.vue) │ │ ├── pages/ → 各画面のルートとなる 画面コンポーネント(.vue) │ │ └── parts/ → 各画面で利用される 部品コンポーネント(.vue) │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/

Slide 8

Slide 8 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ → API通信を行う関数をまとめたファイル( .repo.ts) │ ├── stores/ │ └── types/ ├── stories/ └── tests/

Slide 9

Slide 9 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ → API通信の結果など状態を保持しておく Vuexファイル(.store.ts) │ └── types/ ├── stories/ └── tests/

Slide 10

Slide 10 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ → TypeScriptの型情報を記載しておくファイル( .type.ts) ├── stories/ └── tests/

Slide 11

Slide 11 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ → storybookによるコンポーネントカタログのファイル( .stories.ts) └── tests/

Slide 12

Slide 12 text

ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/ → Jest, Testing Library によるテストコードのファイル( .spec.ts)

Slide 13

Slide 13 text

ディレクトリ構成見直し:導入 page part base store repository logic test sotires logic test component test

Slide 14

Slide 14 text

ディレクトリ構成見直し:問題点① src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ → どの画面で使われてるのか分かりにくい。。 │ ├── repositories/ │ ├── stores/ → どの画面で状態が変更されるのか追いにくい。。 │ └── types/ ├── stories/ └── tests/

Slide 15

Slide 15 text

ディレクトリ構成見直し:問題点① src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ → どのコンポーネントに対して実装済みか分かりにくい。。 └── tests/ → どのコンポーネントに対して実装済みか分かりにくい。。

Slide 16

Slide 16 text

ディレクトリ構成見直し:問題点① src/ ├── app/ │ ├── components/ │ │ ├── base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/ どの画面・どのコンポーネント に所属しているのかが分かれば良さそう ↓ pageコンポーネント中心に集めてみる

Slide 17

Slide 17 text

ディレクトリ構成見直し:partsファイル components/ ├── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── parts/ └── pc/ └── admin/ └── department-list/ └── admin-department-form/ └── AdminDepartmentForm.vue components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── parts/ └── department-form/ └── DepartmentForm.vue before after

Slide 18

Slide 18 text

ディレクトリ構成見直し:partsファイル components/ ├── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── parts/ └── pc/ └── admin/ └── admin-department-form/ └── AdminDepartmentForm.vue components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── parts/ └── department-form/ └── DepartmentForm.vue before after ● 利用される画面が分かりや すくなった ● フォルダ名やファイル名が シンプルになった ● 階層を合わせる必要もなく なった

Slide 19

Slide 19 text

ディレクトリ構成見直し:storeファイル app/ ├── components/ │ └── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── stores/ └── Department.ts components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── store/ └── AdminDepartmentListPc.store.ts before after

Slide 20

Slide 20 text

ディレクトリ構成見直し:storeファイル app/ ├── components/ │ └── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── stores/ └── Department.ts components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── store/ └── AdminDepartmentListPc.store.ts before after ● 更新される画面が分かりや すくなった ● グローバルなStoreから画 面専用のStoreになったの で、他画面の影響を受けな くなった

Slide 21

Slide 21 text

ディレクトリ構成見直し:typeファイル app/ ├── components/ │ └── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── types/ └── department.type.ts components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── AdminDepartmentListPc.type.ts before after

Slide 22

Slide 22 text

ディレクトリ構成見直し:specファイル src/ ├── app/ │ └── components/ │ └── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── tests/ └── app/ 〜 省略 〜 └── AdminDepartmentListPc.it.spec.ts components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── AdminDepartmentListPc.it.spec.ts before after

Slide 23

Slide 23 text

ディレクトリ構成見直し:stories src/ ├── app/ │ └── components/ │ └── pages/ │ └── pc/ │ └── admin/ │ └── department-list/ │ └── AdminDepartmentListPc.vue └── stories/ └── app/ 〜 省略 〜 └── AdminDepartmentListPc.stories.ts components/ └── pages/ └── pc/ └── admin/ └── department-list/ ├── AdminDepartmentListPc.vue └── AdminDepartmentListPc.stories.ts before after

Slide 24

Slide 24 text

ディレクトリ構成見直し:まとめ① components/ └── pages/ └── pc/ └── admin/ └── department-list ├── AdminDepartmentListPc.vue ├── AdminDepartmentListPc.type.ts ├── AdminDepartmentListPc.it.spec.ts ├── AdminDepartmentListPc.stories.ts ├── parts │ └── department-form │ └── DepartmentForm.vue └── store └── AdminDepartmentListPc.store.ts after pageコンポーネント中心に集めて 各ファイルの利用箇所が分かりや すくやった (責務の分離もできた)

Slide 25

Slide 25 text

ディレクトリ構成見直し:問題点② page part base store repository logic test sotires logic test component test ビジネスロジックが 多くなりがち テストが書きにくい ビジネスロジックが 多くなりがち テストが書きにくい

Slide 26

Slide 26 text

ディレクトリ構成見直し:問題点② page part base store repository logic test sotires logic test component test modules modules ● ビジネスロジックを抜き出す階層を作成 ● export/importでテストも書くやすくする

Slide 27

Slide 27 text

ディレクトリ構成見直し:modules components/ └── pages/ └── pc/ └── admin/ └── department-list ├── AdminDepartmentListPc.vue ├── AdminDepartmentListPc.type.ts ├── AdminDepartmentListPc.it.spec.ts ├── AdminDepartmentListPc.stories.ts ├── parts │ └── department-form │ └── DepartmentForm.vue └── store └── AdminDepartmentListPc.store.ts components/ └── pages/ └── pc/ └── admin/ └── department-list ├── AdminDepartmentListPc.vue ├── AdminDepartmentListPc.type.ts ├── AdminDepartmentListPc.it.spec.ts ├── AdminDepartmentListPc.stories.ts ├── AdminDepartmentListPc.modules.ts ├── AdminDepartmentListPc.modules.spec.ts ├── parts │ └── department-form │ └── DepartmentForm.vue └── store └── AdminDepartmentListPc.store.ts before after

Slide 28

Slide 28 text

ディレクトリ構成見直し:modules components/ └── pages/ └── pc/ └── admin/ └── department-list ├── AdminDepartmentListPc.vue ├── AdminDepartmentListPc.type.ts ├── AdminDepartmentListPc.it.spec.ts ├── AdminDepartmentListPc.stories.ts ├── parts │ └── department-form │ └── DepartmentForm.vue └── store └── AdminDepartmentListPc.store.ts components/ └── pages/ └── pc/ └── admin/ └── department-list ├── AdminDepartmentListPc.vue ├── AdminDepartmentListPc.type.ts ├── AdminDepartmentListPc.it.spec.ts ├── AdminDepartmentListPc.stories.ts ├── AdminDepartmentListPc.modules.ts ├── AdminDepartmentListPc.modules.spec.ts ├── parts │ └── department-form │ └── DepartmentForm.vue └── store └── AdminDepartmentListPc.store.ts before after ● pageコンポーネントの肥大 化を防げた ● ロジックを抜き出したおかげ でテストも書きやすくなった

Slide 29

Slide 29 text

ディレクトリ構成見直し:Pros/Cons Pros ● 各ファイルの影響箇所が分かりやす くなった ● ロジック抜き出しによってコンポーネ ントやStoreの肥大化を防げた ● テストも書きやすくなった Cons ● 共通化が減るので実装工数は増え た ● 実装漏れには気をつける必要があ る ● 画面特有のものにするか、共通のも のにするかの判断が難しいものもあ る ● 移行作業を行うには工数がかかる ○ デグレチェック ○ コンフリクト解消

Slide 30

Slide 30 text

まとめ ● 開発フェーズによって適切な設計は異なる ● 楽楽勤怠では品質(保守性)重視での設計見直しを行った ● 画面コンポーネント中心の設計にすることで修正の影響範囲が分かり やすくなった ● ビジネスロジックの抜き出し層を設けたおかげでテストも書きやすくなっ た ● 全て画面の持ち物にすることは不可能なので共通部分は消せない、使 い分けはしていく必要がある

Slide 31

Slide 31 text

ありがとうございました!