Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
フロントエンドの複雑さに耐えるため実践したこと / readyfor-nextjs-first
Search
Takepepe
February 05, 2021
Technology
25
11k
フロントエンドの複雑さに耐えるため実践したこと / readyfor-nextjs-first
【READYFOR】実践!フロントエンド分離戦略::発表資料
https://readyfor.connpass.com/event/198730/
Takepepe
February 05, 2021
Tweet
Share
More Decks by Takepepe
See All by Takepepe
ServerAction で Progressive Enhancement はどこまで頑張れるか? / progressive-enhancement-with-server-action
takefumiyoshii
7
900
App Router への移行は「改善」となり得るのか?/ Can migration to App Router be an improvement
takefumiyoshii
8
3.2k
フロントエンドの書くべきだったテスト、書かなくてよかったテスト
takefumiyoshii
39
15k
Webフロントエンドのための実践「テスト」手法 CodeZine Night #1
takefumiyoshii
24
8.5k
Next.js でリアーキテクトした話 / story-of-re-architect-with-nextjs
takefumiyoshii
12
8.7k
より速い WEB を目指す Next.js / nextjs-make-the-web-faster
takefumiyoshii
54
20k
Redux の利点を振り返る
takefumiyoshii
26
8.7k
Type-only Migrate by AST
takefumiyoshii
1
650
- Regular expression & Type - Naming Rule Linter
takefumiyoshii
1
380
Other Decks in Technology
See All in Technology
非機能品質を作り込むための実践アーキテクチャ
knih
5
1.2k
PHP ユーザのための OpenTelemetry 入門 / phpcon2024-opentelemetry
shin1x1
1
200
podman_update_2024-12
orimanabu
1
270
宇宙ベンチャーにおける最近の情シス取り組みについて
axelmizu
0
110
LINE Developersプロダクト(LIFF/LINE Login)におけるフロントエンド開発
lycorptech_jp
PRO
0
120
watsonx.ai Dojo #5 ファインチューニングとInstructLAB
oniak3ibm
PRO
0
160
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
2
110
AWS re:Invent 2024で発表された コードを書く開発者向け機能について
maruto
0
190
オプトインカメラ:UWB測位を応用したオプトイン型のカメラ計測
matthewlujp
0
170
1等無人航空機操縦士一発試験 合格までの道のり ドローンミートアップ@大阪 2024/12/18
excdinc
0
160
2024年にチャレンジしたことを振り返るぞ
mitchan
0
140
Snykで始めるセキュリティ担当者とSREと開発者が楽になる脆弱性対応 / Getting started with Snyk Vulnerability Response
yamaguchitk333
2
180
Featured
See All Featured
Embracing the Ebb and Flow
colly
84
4.5k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
How to Ace a Technical Interview
jacobian
276
23k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Producing Creativity
orderedlist
PRO
341
39k
For a Future-Friendly Web
brad_frost
175
9.4k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
25k
BBQ
matthewcrist
85
9.4k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5k
Transcript
READYFOR x Next.js フロントエンドの複雑さに耐えるため実践したこと @ Takepepe
READYFOR フロントエンド分離のゴール ▪ BE/FE の責務をわけ、疎結合とすること ▪ 時代に即したベストプラクティスを追求できること #readyfor_meetup
READYFOR フロントエンド分離のゴール これまでモノリスだった RoR の アプリケーションサーバーは APIサーバーへ。 View はJS(TS)だけで完結する姿へ…
#readyfor_meetup
READYFOR フロントエンド分離のゴール Next.js はこういった背景のプロダクトで選ばれる、 筆頭の選択肢となりました。 静的キャッシュ恩恵・ゼロコンフィグ、 SSR ハイブリッドなど、要件に合わせやすいです。 #readyfor_meetup
参画の経緯と当時の状況 READYFOR からお誘いをうけ 委託参画したのが昨年4月。 この10ヶ月間で2つの Next.js 案件 立ち上げをお手伝いしました。 #readyfor_meetup
参画の経緯と当時の状況 すでに分離戦略が敷かれていたため、 わたしの担当は明確でした。 デザインシステム(READYFOR Elements)を利用 して、Next.js App を構築することです。 #readyfor_meetup
参画の経緯と当時の状況 ▪ RoR アプリケーション一部に、react_on_rails ▪ READYFOR Elements が仕上がっていた ▪ Next.js
製の PoC があった #readyfor_meetup
参画の経緯と当時の状況 Next.js / SPA 化にともない、フロントエンドが抱える 表示ロジックが複雑になることが想定されました。 その複雑さを乗り越える設計・実装を どの様に行ったのかを、本日お話します。 #readyfor_meetup
Redux の参照秩序
はじめに手掛けた「実行者SPA」は、 細かな UI の部分再描画が頻出する要件でした。 状態管理ライブラリに Redux を選定しました。 Redux を選んだ理由 #readyfor_meetup
Redux を選んだ理由 ▪ 算出値のメモ化と、部分再描画に優れている ▪ devtools が他ソリューションと比較し充実している ▪ integration test
が実施しやすい #readyfor_meetup
Redux は「秩序が生まれやすい」と定評がありますが、 使い方次第では「無秩序」になりやすいものです。 採用の際には、ガイドラインが必要です。 Redux の懸念点 #readyfor_meetup
参照秩序 のガイドライン ファイル構成は Re-ducks パターンとしました。 関心範囲を境界とし、 Module 毎で管理。 ├── redux
├── A ├── B ├── C ├── D ├── index.ts ├── reducers.ts └── store.ts #readyfor_meetup
参照秩序 のガイドライン ├── redux ├── A ├── B ├── C
├── D ├── index.ts ├── reducers.ts └── store.ts ファイル構成は Re-ducks パターンとしました。 関心範囲を境界とし、 Module 毎で管理。 Module #readyfor_meetup
参照秩序 のガイドライン ├── redux ├── A ├── B ├── C
├── D ├── index.ts ├── reducers.ts └── store.ts Module の内訳は以下のとおり。 State を軸とした定義を保有します。 state.ts / reducer.ts / actions.ts selectors.ts / thunks.ts #readyfor_meetup
参照秩序 のガイドライン ├── redux ├── A ├── B ├── C
├── D ├── index.ts ├── reducers.ts └── store.ts この Module 同士は、 参照関係をもつことができます。 #readyfor_meetup
参照秩序 のガイドライン ├── redux ├── A ├── B ├── C
├── D ├── index.ts ├── reducers.ts └── store.ts 例えば「A」で発行された 「A」のための Action を、 「C・B」でも購読する、 という参照関係です。 #readyfor_meetup
参照秩序 のガイドライン ├── redux ├── A ├── B ├── C
├── D ├── index.ts ├── reducers.ts └── store.ts この参照秩序が保たれなければ、 スパゲティコードが生まれます。 Reducer と Selector で、 この参照捻れは発生し得ます。 #readyfor_meetup
参照秩序 のガイドライン 参照秩序は公式ガイドの Basic State Shape を参考に、 「Module prefix」で明文化しました。 https://redux.js.org/recipes/structuring-reducers/basic-reducer-structure#basic-state-shape
#readyfor_meetup
Module prefix ?
参照秩序 のガイドライン Api** App** UI** Page** Module prefix を4つに区分。 prefix
により、参照権限が異なります。
参照秩序 のガイドライン(prefix: Api***) Api** App** UI** Page** API レスポンスを「取得・保持」するのみ。 API
path と1対1で設け「別 Module は参照しない」
参照秩序 のガイドライン(prefix: App***) App** UI** Page** アプリケーションで横断的に利用する値を管理。 また「API・App」Module しか参照できない。 Api**
参照秩序 のガイドライン(prefix: UI***) UI** Page** Global UI に関連する状態しか持たない。 また「API・App・UI」しか参照できない。 Api**
App**
参照秩序 のガイドライン(prefix: Page***) Page** 全ての値と Action を参照できる。 Page Component と1対1。
Api** App** UI**
参照秩序 のガイドライン(prefix: Page***) 「下流 Module が上流 Module を参照する」という、 シンプルな命名規則による参照秩序を設けました。 Api**
App** UI** Page** 上流 下流
このガイドラインの目的は、 参照権限を限定することで、 責務の所在を明確にすることです。 参照秩序 のガイドライン #readyfor_meetup
責務の所在地が明確であれば、 設計の属人化が最小限になります。 そして、必要な責務のみが下流に降りてきます。 参照秩序 のガイドライン #readyfor_meetup
参照秩序 のガイドライン Page** この関係とすることで、特定ページ専用の「Page**」Module は、 特定ページの処理のみに、専念することができます。 Api** App** UI**
参照秩序 のガイドライン ▪ 実装中に異常な参照捻れに気付ける ▪ コンテキスト理解が容易くレビュー負荷も下がる 命名規則だけで、開発体験はよりよくなる! #readyfor_meetup
Cypress 実践 BDD
Cypress で実践する BDD 表示分岐ロジックが複雑になることが想定されたため、 integration テストは不可欠としていました。 そのため、後発の Prj は立ち上げ初期から BDD
を採用しました。 #readyfor_meetup
Cypress で実践する BDD これから作成しようとするプログラムに 期待される「振る舞い」や「制約条件」、 つまり「要求仕様」に近い形で、 自然言語を併記しながらテストコードを記述する。 引用:https://ja.wikipedia.org/wiki/ビヘイビア駆動開発 #readyfor_meetup
Cypress で実践する BDD 実践にあたり採用したのが Cypress です。 Cypress は動作が軽快で BDD に適した
テストフレームワークです。 #readyfor_meetup
Cypress で実践する BDD Redux と Cypress は相性がよく、 Action dispatch で特定条件の再現が可能です。
こういった場面で、Redux の特性が活きてきます。 #readyfor_meetup
Cypress で実践する BDD 混み入った分岐条件でのみ現れる画面も、 どの「状態・Action」があれば再現できるのか? が、テストコードに落ちてきます。 #readyfor_meetup
Cypress で実践する BDD 特定制約時を再現するの事が容易なため、 テストファイルを細分化できます。 表示を即座に確認できるため、 ドキュメントとしても役立ちます。 #readyfor_meetup
None
Cypress で実践する BDD また、OpenAPI 定義によるMock サーバーを、 Cypress integration テストにも 活用しました。
#readyfor_meetup
Cypress で実践する BDD 「テストを書きやすい」環境は、 ライブラリ・ツール選択で明らかに 差が出てきます。 #readyfor_meetup
Cypress で実践する BDD また、ワークフローの工夫も大切です。 タスク分解の段階で「書きやすさ」は変わります。 タスクを細分化し、十分小さくすることです。 #readyfor_meetup
Cypress で実践する BDD チケットを発行し、チケット番号とともに 要求仕様の「空テスト」をコミット。 describe("「支払い方法」そのものが表示されない条件 ", () =>
{ xit("最終確認ページから「リターンを変更する」ために戻ってきた場合 ", () => { // TODO: #567 }); });
Cypress で実践する BDD PR とともに実装内容がテストに記されているため、 PR 概要を詳に書かずとも概要が伝わる状態が理想です。 describe("「支払い方法」そのものが表示されない条件 ",
() => { - xit("最終確認ページから「リターンを変更する」ために戻ってきた場合 ", () => { + it("最終確認ページから「リターンを変更する」ために戻ってきた場合 ", () => { }); });
Cypress で実践する BDD ライブラリ側もテストツール群も、 得意・不得意(オーバースペック)があります。 ライブラリ選定の際には「テスト観点」も含め、 バランスをとりながら選ぶ必要があります。 #readyfor_meetup
振り返りと 今後
制御・非制御 Component の I/F READYFOR Elements の再利用は とても上手くいきました。 しかし、一部検討余地がありました。
#readyfor_meetup
制御・非制御 Component の I/F たとえば、非制御 Component + Form 前提の props
設計が紛れていた事。 Form 都合の props を剥がすリファクタリングに 想定以上の工数がかかりました。 #readyfor_meetup
制御・非制御 Component の I/F また、制御 Component と比べると、 非制御 Component は
Redux と 相性がよくありません。 #readyfor_meetup
制御・非制御 Component の I/F React on Rails で利用していた箇所としては、 非制御 Component
がベストだった背景がそこに。 移行に必要なコストに違いないものです。 #readyfor_meetup
制御・非制御 Component の I/F READYFOR Elements の様な横断的な デザインシステムを構築するのなら、 制御・非制御 Component
を選択できる様な I/F を初期設計から盛り込むべきです。 #readyfor_meetup
これからも Redux を使いつづけるか? useContextSelector など、 Redux(useSelector) の代替となる様な React 公式 API
の検討も始まっており、 状態管理ライブラリ選定はやはり悩みどころです。 #readyfor_meetup
これからも Redux を使いつづけるか? これからも Redux を使いつづけるか? というと「都度検討」だと思います。 readyfor は機能単位で Next.js
を分割しているため、 状態管理も機能要件にあわせて選択できます。 #readyfor_meetup
これからも Redux を使いつづけるか? Redux のテスト優位性をあげたとおり、 フロントに複雑な表示ロジックを置く場合は、 導入メリットが多いです。 #readyfor_meetup
これからも Redux を使いつづけるか? 表示ロジックがフロントに寄る場合は採用、 表示ロジックがサーバーに寄る場合は不採用、 という切り分けをすると思います。 #readyfor_meetup
READYFOR の フロントエンドの分離戦略は スタートを切ったばかりです。 #readyfor_meetup
またいつか、 この続きを共有できる事を 楽しみにしています。 #readyfor_meetup
READYFOR x Next.js ご清聴ありがとうございました!