Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
フロントエンド_最強ディレクトリ構成
Search
hatsune
December 07, 2022
Programming
5.3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
フロントエンド_最強ディレクトリ構成
hatsune
December 07, 2022
More Decks by hatsune
See All by hatsune
Vue_CLIプロジェクトにViteを導入検討してみた
kitsuneeee
1
8.2k
Vue.js + TypeScriptによる 新規サービス開発の振り返り/frontend-looking-back
kitsuneeee
4
2.2k
コンポーネント間のデータやりとりを色々試してみた.pdf
kitsuneeee
0
530
Other Decks in Programming
See All in Programming
新卒PdEのリアル
ryu1013
1
480
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.9k
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
520
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
5.6k
スマート反転とウェブアクセシビリティ
camiha
0
170
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
140
不幸な GC
chencmd
0
890
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
120
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
360
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
140
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
130
Foundry Localでエージェント開発
seosoft
0
160
Featured
See All Featured
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Scaling GitHub
holman
464
140k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
930
Believing is Seeing
oripsolob
1
210
How to train your dragon (web standard)
notwaldorf
97
6.8k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
BBQ
matthewcrist
89
10k
Tell your own story through comics
letsgokoyo
1
1.1k
A Tale of Four Properties
chriscoyier
163
24k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
370
Transcript
フロントエンド 最強ディレクトリ構成 株式会社ラクス 勤怠開発2課 北嶋初音
index • 発表経緯 • 開発フェーズによる特徴 • 利用技術 • ディレクトリ構成見直し •
まとめ
発表経緯 • 楽楽勤怠のリリースから約2年 • 開発も運用フェーズへと移行しつつある • ディレクトリ設計の見直しもたびたび必要があった • 設計方針がある程度固まってきたので共有 •
経緯や具体的な移行内容をまとめておく
開発フェーズによる特徴 初期 開発スピード重視 • 共通化 ◦ 1箇所直したらで全部直って欲 しい • 機能要件が満たせればOK
現在 品質(保守性)重視 • 責務の分割 ◦ デグレを防止したい ◦ 修正の影響箇所を絞りたい • テストコードも書きたい
利用技術 • Vue.js(2系) • Vuex • TypeScript • Axios •
Jest • Testing Library • Storybook ※今回分かっておけば良い部分のみ記載
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ → 複数画面で利用される 共通コンポーネント(.vue) │ │ ├── pages/ → 各画面のルートとなる 画面コンポーネント(.vue) │ │ └── parts/ → 各画面で利用される 部品コンポーネント(.vue) │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ → API通信を行う関数をまとめたファイル( .repo.ts) │ ├── stores/ │ └── types/ ├── stories/ └── tests/
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ → API通信の結果など状態を保持しておく Vuexファイル(.store.ts) │ └── types/ ├── stories/ └── tests/
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ → TypeScriptの型情報を記載しておくファイル( .type.ts) ├── stories/ └── tests/
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ → storybookによるコンポーネントカタログのファイル( .stories.ts) └── tests/
ディレクトリ構成見直し:導入 src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/ → Jest, Testing Library によるテストコードのファイル( .spec.ts)
ディレクトリ構成見直し:導入 page part base store repository logic test sotires logic
test component test
ディレクトリ構成見直し:問題点① src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ → どの画面で使われてるのか分かりにくい。。 │ ├── repositories/ │ ├── stores/ → どの画面で状態が変更されるのか追いにくい。。 │ └── types/ ├── stories/ └── tests/
ディレクトリ構成見直し:問題点① src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ → どのコンポーネントに対して実装済みか分かりにくい。。 └── tests/ → どのコンポーネントに対して実装済みか分かりにくい。。
ディレクトリ構成見直し:問題点① src/ ├── app/ │ ├── components/ │ │ ├──
base/ │ │ ├── pages/ │ │ └── parts/ │ ├── repositories/ │ ├── stores/ │ └── types/ ├── stories/ └── tests/ どの画面・どのコンポーネント に所属しているのかが分かれば良さそう ↓ pageコンポーネント中心に集めてみる
ディレクトリ構成見直し: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
ディレクトリ構成見直し: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 • 利用される画面が分かりや すくなった • フォルダ名やファイル名が シンプルになった • 階層を合わせる必要もなく なった
ディレクトリ構成見直し: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ファイル 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になったの で、他画面の影響を受けな くなった
ディレクトリ構成見直し: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
ディレクトリ構成見直し: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
ディレクトリ構成見直し: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
ディレクトリ構成見直し:まとめ① 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コンポーネント中心に集めて 各ファイルの利用箇所が分かりや すくやった (責務の分離もできた)
ディレクトリ構成見直し:問題点② page part base store repository logic test sotires logic
test component test ビジネスロジックが 多くなりがち テストが書きにくい ビジネスロジックが 多くなりがち テストが書きにくい
ディレクトリ構成見直し:問題点② page part base store repository logic test sotires logic
test component test modules modules • ビジネスロジックを抜き出す階層を作成 • export/importでテストも書くやすくする
ディレクトリ構成見直し: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
ディレクトリ構成見直し: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コンポーネントの肥大 化を防げた • ロジックを抜き出したおかげ でテストも書きやすくなった
ディレクトリ構成見直し:Pros/Cons Pros • 各ファイルの影響箇所が分かりやす くなった • ロジック抜き出しによってコンポーネ ントやStoreの肥大化を防げた • テストも書きやすくなった
Cons • 共通化が減るので実装工数は増え た • 実装漏れには気をつける必要があ る • 画面特有のものにするか、共通のも のにするかの判断が難しいものもあ る • 移行作業を行うには工数がかかる ◦ デグレチェック ◦ コンフリクト解消
まとめ • 開発フェーズによって適切な設計は異なる • 楽楽勤怠では品質(保守性)重視での設計見直しを行った • 画面コンポーネント中心の設計にすることで修正の影響範囲が分かり やすくなった • ビジネスロジックの抜き出し層を設けたおかげでテストも書きやすくなっ
た • 全て画面の持ち物にすることは不可能なので共通部分は消せない、使 い分けはしていく必要がある
ありがとうございました!