Open15

モジュラフロントエンドのメモ

ピン留めされたアイテム

このスクラップは?

SPA において(レイヤーではなく)表示領域ごとの分割統治方法をメモしていく。スパム的なものを以外、誰がコメントを付けても構わない。
(リンクが無いものも自分がふと見かけた別のエンジニアのアイデアがベースになっている)

分割統治することで、領域の関心がシンプルになり理解しやすくなるし UI の歪みも明らかになる。また、レイヤーを減らすことで、領域全体を一目で把握しやすく、また、実装しやすく破棄しやすくする。

ただし、サーバー等でのプラクティスであるモジュラモノリスレベルでの分割を SPA で実現するのは、相互作用の多さから不可能だろう。

別の目的で作られたとはいえ、こうしややり方に借用できるツールやライブラリが整ってきたことにより、現実的になりつつあると考えている。

ビジネスを実装すべき。

ビジネスは従来のソフトウェアよりも速く変化する。従来のソフトウェアで良いとされていたものでも、ビジネスの速度に追いつけないなら利用できない。

フロントエンドが DSL と化して、ビジネスを誰でも簡単に保守性高く高速に実現できるようになると良いのだろうか。

フロントエンドにおけるモデルについて

サーバーと違い、フロントエンドには長く残すべきドメインモデルのようなモデル[1]はない。フロントエンドの関心は UI とそれにまつわる必要な処理だが、それらは頻繁に変わる。フロントエンドでの短命のモデルに変更を加え続けるよりも、レイヤーやモデルの存在を気にせず E2E でべた書きした方が将来の保守性・実装速度が上という状況はあり得る。

レイヤードアーキテクチャ[2]は良く知られた有効なプラクティスで、普通のサーバーのコードであればレイヤー毎に関心は整い良いコードが書きやすいだろう。一方で、「ブレークスルー」による再モデリングではない文脈で、他と同化したドメインモデル・ユースケースの一部分を取り除くのは影響範囲を確認しつつの作業となるため面倒だろう。サーバーではどういう状況でこうした要求が発生するのか私にはわからないが、ほぼ起きないならば問題にならないと思う。一方、フロントエンドでは UI デザインの変更でその処理が不要になることはある。

短命なモデルしかないフロントエンドに、レイヤードアーキテクチャはどの程度役に立つのだろうか。


ちなみに、フロントエンドでのバリデーションロジックはドメインモデルではないか?という意見はあると思う。これについては、サーバーのバリデーションがデータやビジネスの整合性を維持するためのものであるのに対し、フロントエンドのバリエーションはユーザビリティ向上のためにあることを考えると良い。
フロントエンドではユーザビリティのためにサーバーと違うチェック・表示も可能で、ビジネスロジックとは別に、それと無関係に UI デザインや UX ライティング上の要求として実装できる。

脚注
  1. DDD でのモデル・ビジネスロジックはサーバーの更新系を意図している。一方の参照系のリードモデルは柔軟に書けたり変えられたりした方が良いという意見があったと記憶している(手前味噌だがまとめは https://blog.masuqat.net/2020/11/03/system-mode-border/ )。このくくりでは、フロントエンドは参照系にあたるので、フロントエンドのモデルはこうしたドメインモデルとは性質が異なる。 ↩︎

  2. 関心毎にレイヤーに分けることで、理解しやすく技術的変更に強いコードを目指す。ヘキサゴナルアーキテクチャのようにレイヤーの分け方をうまくとると、ドメインモデルやビジネスロジックを不要な技術的詳細の影響から守ることができる。 ↩︎

コンパイラは比較的キレイにレイヤリング可能なプログラムなので、コンパイラばかり書いている人たちにとってはそれこそが正しいデザインに思えたのだろう。

リンカと比較できるものではないが、私見ではフロントはきれいにレイヤリングできない、もしくは、効果が薄い。

https://note.com/ruiu/n/n9948f0cc3ed3

把握しやすいミニマムなコード

領域全体を常にすぐに把握しやすい状態に保つことができれば追加実装しやすい。レイヤードアーキテクチャの欠点はボイラープレート的コードが必要になることと、E2E での把握がしにくくなる[1]ことだ。

フロントエンドではJSON色付け係という言葉があるようにサーバーから取得したデータをユーザーに見せる処理で完結する場合も多く、その中間のロジックもあまりないので技術的詳細を隠蔽してもあまりうれしくない。フォームをはじめユーザーに操作してもらうところも多いが、こちらも HTML の仕様と強く結びついているので隠蔽の旨味は少ないと思う[2]

そうであれば、むしろレイヤーを取っ払って、データ取得と表示を近くに書いてみたらどうだろうか。ボイラープレートが減って E2E での把握もしやすい、把握しやすくミニマムなコードができるのではないか。
(ドメインモデルがあるような普通のサーバー的には失格かもしれないが)

脚注
  1. サーバーで例えると、特定の Web フレームワーク(Express/Rails Action Controller)が HTTP リクエストを受け取り、ユースケースを介してドメインモデルで演算し、特定のデータストア(MongoDB/PostgreSQL)に保存する、という流れを把握すること。これは表裏一体で、これらが隠蔽されるのがレイヤードアーキテクチャの利点の一つ。 ↩︎

  2. スクラップ作成者に React Native 等の経験が無いので言い切れるかよくわからずこのような言い回しになっている。 ↩︎

捨てる障壁を低いということ

今の実装(の一部分)を捨てて作り直すすることに躊躇しなくなると何がうれしいか。フロントエンドで(一部分の)実装を捨てるという事態は、負債解消や機能追加等の実装上の理由だけでなく、UI デザインの変更や検証で部分的に作り変える、という理由でも起きる。

むしろ、現実の使い捨て製品のように、捨てるコストが低い方が運用の柔軟さに勝り、実装や UI デザインの試行錯誤や改善が行いやすい。

「犠牲的アーキテクチャ」なのかもしれない。

CSS の技術

TODO: Utility-First CSS

デザイントークンの反映と必要最小限のセマンティクス

コンポーネント設計

TODO: Atomic Design の Organisms

API アクセス

TODO: GraphQL

-> render-as-you-fetch パターン、fetch の物理処理と論理処理をつなぐアジャスターとしての fetch ライブラリが必要

物理処理:実際に飛ぶリクエストのこと
論理処理:特定のデータを(利用者が感知しない何かしらの方法で)取得すること

demand 型

更新波及が宣言的

TODO: msw によるモック

https://zenn.dev/saboyutaka/articles/680542da534de5
  • SoEの要件の変化の速さについていけない
  • UIに正解がない ≒ APIのモデリングに正解がない

残し続けるべきものは何か?

デザインシステム

TODO

スピードを落とさないために指針が必要。

UI デザインを改善し続ける姿勢

TODO

既存実装を気にしない。捨てるのを躊躇しない。

実装能力

捨てられる構造だからと言って、書き捨て的な汚いコードを書いてよいわけではない。あくまで全体のコード量を抑え見やすくし、かつ、捨てる際のコストを低くすることが目的だ。

むしろ要求される能力は増える。機能追加の際に、コードが膨れないようにしたり、UI デザイン変更で一部を作り直すときに(ボイラープレートなコードを追加・削除する時間が不要になる分だけ)実装の質と速度がエンジニアの実装の質と速度により依存するだろう。

コンポーネントカタログ・テスト

TODO

内部ステート化による網羅の難しさ
-> storybook addon interaction

VRT

カタログのテスト転用

React Cuncurrent Rendering Suspense

TODO

全てのコンポーネントがサスペンドする可能性がある。そのために、逆に、利用するコンポーネントの中の処理を見に行かなくてよくなる。
親が子の読み込み状態を(分割統治上)適切にしやすくなるため。

ログインするとコメントできます