対象読者
- AngularやReactなどのフレームワークに頼らずに再利用可能なHTMLやCSSを整備したいマークアップエンジニア
- AngularやReactなどのフレームワークとWeb Componentsを併用する利点を学びたいJavaScriptエンジニア
前提環境
筆者の検証環境は以下の通りです。
- macOS Monterey 12.3.1
- Google Chrome 100.0.4896.127
Webサイト制作におけるソースコード整理の課題
インターネットの歴史における遥か昔、Webサイトは、ブラウザ上にHTMLだけを読み込ませれば表示できるものでした。その後、CSSを読み込ませることで視認性に優れたWebサイトを装飾・レイアウトできるようになり、JavaScriptを読み込ませることでアプリケーションも作れるほどに進化しました。
この進化の過程で、Webサイト制作に必要なコード量は肥大化し、複雑になっていきました。一般論として、大きく複雑なものは、人間が認知可能なサイズまで整理して細分化しないと、以降の改修の手を入れづらくなります。Webサイト制作の進化の歴史は、ソースコードを整理する歴史でもあるのです。
とはいっても、整理するのは簡単なことではありません。特にHTMLとCSSの関係を理想的に保つのは難しいものになっています。理想としては、「意図した変更は行いやすい柔軟さ」と「ある変更によって意図しない箇所が壊れない堅牢さ」が両立できたらよいのですが、実際にはクラス名が意図せず重複して関係ない場所のスタイルが崩れてしまったり、ガチガチにCSSセレクタを定義して堅牢にすることでHTMLの文書構造を変更しづらくなってしまったりと、ままならないものです。
どうにかしてUIを「部品」のような形に整理できるとよさそうです。もしUIを再利用可能な部品として定義できれば、同じような見た目のものは一度実装したものをソースコードのコピペを行うことなく使い回したり、部品内部の変更が部品の外部に影響するのを防いだりするできるかもしれません。それができたらどれだけ嬉しいことでしょう。
そういった特性は、プログラミングの世界で「再利用性」と「カプセル化」という言葉で呼ばれています。本記事では、再利用性とカプセル化の特性を持った、部品化されたUIをブラウザで扱う手法について解説します。
再利用性とカプセル化
もう少し、再利用性とカプセル化について理解を深めておきましょう。
本記事では、「再利用性」という言葉を「一度書いたコードを再度呼び出して利用できること」とします。JavaScriptのfunction構文で定義した関数や、注意深く設計されたCSS実装は、複数の場所から利用することができますね。同じ処理を何度も書かなくてよいというのは、それだけで十分にメリットですが、修正が必要になった場合にも1カ所だけ修正すればよい、というメンテナンス上のメリットもあります。
また、「カプセル化」という言葉は「ある部品の中に書いたコードを変更したときに、部品の外にあるコードの動作に影響を与えないこと、また、他の部品の変更から影響を受けないこと」とします。コードを作成・修正しているときに、他のコードを壊さないことや、せっかく書いたコードが関係ないコードに壊されないことは、安心感を生み出します。安心感は将来の改修において余計な心配を排除し、結果的に実装時間を短縮するので、継続的な開発においてはぜひ持ちたい特性です。
再利用性やカプセル化という概念は特段珍しいものではなく、Webサイト制作の歴史の中でも度々試みられてきました。CSSの分野ではBEM(Block Element Modifier)をはじめとした「クラス名を複雑にする」アプローチによって、クラス名が被らないようにすることで、カプセル化に近い効果を得ているように見えます。
また、近年高い評価を得ているtailwindcssは、細かい粒度でスタイル定義を行うことで、再利用性の高いCSSライブラリに仕上がっています。JavaScriptにもimport/export構文によるモジュール機構が実装され、再利用性が高まってきています。
HTML(文書構造)の分野では、JavaScriptのライブラリ(Angular、React、Vue.jsなど)によってUI部品を作成し、再利用性とカプセル化を担保する文化が根強く形成されました。このアプローチでもUI部品の作成や、それらを組み合わせる形でのWebサイト制作は実施できるのですが、構成管理や状態管理のためのツールとしての色合いが強いため、「UI部品を作る」という目的にとっては、やや過剰な機能を持っているといえるでしょう。
UIを部品化して管理する目的ではReactなどを使ってもよいのですが、Node.jsやNPMなどのコマンドラインツールに頼ったアプローチになるため、ブラウザの外側のツールを増やしたくない人にとっては学習コストが高くなってしまうのが難点です。