コンポーネント指向を支える技術
はじめに
フロントエンド開発の世界は、React、Vue、Angularなどのフレームワークの台頭によって大きく変貌を遂げました。
これらのフレームワークが登場してから数年が経ち、開発手法は成熟しています。
これらモダンなフレームワークに共通する最も重要な概念は「コンポーネント」であったと思います。
現在のフロントエンド開発はコンポーネントが中心であるといっても過言ではないように感じます。
当記事は、コンポーネント指向という言葉を用いてフロントエンド開発を取り巻く技術の整理を試みます。
コンポーネント指向とは何か
コンポーネント指向は、フロントエンド開発においてコンポーネントを中心に据えるアプローチとします。
この方法では、アプリケーションは個々のコンポーネントの組み合わせによって構築されます。
具体的には、例えば特定のページを作成する際に、まずはそのページに必要なコンポーネントを個別に設計し、その後これらのコンポーネントを組み合わせて全体のページを形成します。
コンポーネント指向の難しさ
コンポーネント指向は、開発をコンポーネントに集中させるアプローチですが、実際にこの方法を採用しようとすると、様々な困難に直面します。これらの課題の中心には、HTML/CSSが持つ固有の特性があります。HTML/CSSは以下のような性質を持っています:
- ネストと依存性: HTML要素はネストされた構造を持ち、親子関係に基づいてスタイルや動作が継承されます。この構造は、親要素の変更が子要素に影響を及ぼすため、個々のコンポーネントの独立性を維持することを難しくします。
- 変更の伝播: ツリー内のあるノード(HTML要素)の変更は、他のノードに波及する可能性があります。例えば、CSSスタイルの変更が意図せず他の要素に影響を及ぼすことがあります。これもコンポーネントの独立性を維持することを複雑にします。
これらの特性は、コンポーネントの独立性を保つことを難しくし、結果としてコンポーネント指向のアプローチを難しくさせます。シンプルなHTML/CSSの構造では、ページのような全体感を持つ対象から作る方が合理的な場合があります。実際に、ページ全体のHTML/CSSを作成した後、それをコンポーネントに分割する開発プロセスには、私は何度か経験しましたし一定の合理性があると思っています。
コンポーネント指向の意義
それでもなお、コンポーネントが現代のフロントエンド開発において重要な役割を果たしています。
その理由の1つは、複雑化するアプリケーションの要求にあります。
この文脈で、以下の引用が示唆に富んでいます。
ソフトウェア開発は、ほとんどすべての物理法則を超越できますが、エントロピー増大の法則には強く縛られます。
プリンシプル オブ プログラミング 7.4「エントロピーの法則」[1]より引用
ソフトウェア開発における最大の障害となる原理こそ「エントロピー増大の法則」です。
これは複雑性という言葉でも言及され、ソフトウェア開発は結局のところ複雑性との戦いであるとも言われます。
実際、数多くのプラクティスは「複雑性を最小化する」ための試みであると考えられます。
さて複雑性を最小化する試みを考える上ではソフトウェアが持つ性質を考えることが重要です。
ソフトウェアはほとんどすべての物理法則を超越したおかげなのか、実行と合成が非常に得意です。
実際、数千件であっても自動テストは何度でも短時間で実行できますし、多くのプログラミング言語では単純にコードを並べるだけで処理を合成できます。
この性質からよく知られているベストプラクティスの1つが導かれます。
それはモジュール性のある単一責務を持つコードを個別に作成し、それらの合成によってソフトウェア開発を進めることです。
具体的には、独立したモジュールを作成し、自動テストなどでその動作を保証し、それらを組み合わせてソフトウェアを構築することを意味します。
コンポーネント指向は、この考え方をフロントエンド開発に適用したものです。
フロントエンドで独立して動作するモジュールとしてのコンポーネントを作成し、それらを組み合わせてアプリケーションを構築することで、複雑性を最小限に抑えることを目指しています。
この視点から見ると、コンポーネント指向はソフトウェア開発における既存のプラクティスから自然に導かれるアプローチであると言えます。
コンポーネント指向を支える技術
コンポーネント指向の意義は明らかですが、その実現方法には依然として課題があります。
幸い、現代のフロントエンド開発技術はこのアプローチをサポートするために充実しています。
この技術スタックを巧みに活用することで、コンポーネント指向の実現が現実的なものになると考えています。
Figma
ここで言う「Figma」とは、実際にはFigmaを代表とするデザインツール全般を指します。これらのツールは、コンポーネント指向を実現する上で最も重要な役割を担っています。その理由は、適切なコンポーネント設計のためにはまず、アプリケーション全体の優れた設計が不可欠です。
Figmaのようなツールは、コードから独立してアプリケーションを直感的かつ迅速に設計することを可能にします。これらは軽量で、変更も容易であるため、アプリケーション設計のプロセスにおいて非常に効率的です。設計の柔軟性と速度は、コンポーネント指向のアプローチにおいて重要な要素であり、Figmaなどのツールはこれを強力にサポートします。
React
コンポーネントの枠組みを提供しているのでこれも外せません。
この枠組みの中核を成すのは、特にFunctional Componentの導入です。
Functional Componentを利用することで、コンポーネントは冪等性を持ちます。
つまり、同じステートに対して一貫した出力を返す能力を持つことです。
この冪等性は、コンポーネントの組み合わせを容易にし、コンポーネント指向のアプローチをより効果的にします。
Storybook
コンポーネントは最終的にブラウザで動作するものですが、ページ全体に組み込む形でのテストではフィードバックが遅れがちです。
コンポーネント指向の開発では、ブラウザ上でのコンポーネント単体での実行が可能であることが求められます。
ここで重要な役割を果たすのがStorybookです。
Storybookは、ブラウザ上でコンポーネントを個別に実行するためのサンドボックス環境を提供します。
これにより、開発者はページの他の部分と独立して、コンポーネントの挙動を迅速にテストし、調整することができます。
Testing Library
コンポーネントを個別に作成する際、各コンポーネントの信頼性は重要な考慮事項となります。この課題に対処するのに、Testing Libraryの使用は非常に効果的です。Testing Libraryはコンポーネントの動作を確実に検証し、その信頼性を保証することで、品質の高いアプリケーション開発を支援します。
Testing Libraryの大きな利点は、テストの実行速度が速く、フィードバックを迅速に得られることです。また、外部環境や依存性に縛られずにテストが実行できるため、フィードバックループの安定性と効率が向上します。
SWR
コンポーネント単位でAPIリクエストを行う場合、リクエストの重複によりパフォーマンスが低下することがあります。これは「Network Request Waterfall」として知られる問題です。SWRは、この問題に対する解決策の1つとして利用されます。SWRは重複するAPIリクエストを効率的に管理し、パフォーマンスの最適化を図ります。
これにより、ある程度の独立性を保ちつつパフォーマンスを改善します。
昨今Next.jsのApp Routerでも同様の最適化が試みられています。
これらの進歩は、フロントエンド開発がコンポーネント指向のアプローチに進んでいるように感じられます。
まとめ
現代のフロントエンドは、複雑化するアプリケーションの要求に直面しています。私は、この状況がフロントエンド開発を、ソフトウェア開発の古典的なベストプラクティスに向かわせていると考えています。具体的には、コンポーネントという形のモジュールをきちんと作成し、それらの合成によってアプリケーションを構築するというアプローチです。
このアプローチを実現するための有効な技術を本稿では幾つか紹介しました。
フロントエンドは技術の変遷が速いと言われますが、このコンポーネント指向の視点で技術の変遷を大枠として理解できるのではと考えています。
Discussion