コンポーネント。 AIに開発を頼んでいると、必ず出てくる言葉です。 「コンポーネントに分けましょう」と言われて、なんとなく頷いた経験がある人は多いと思います。
分かりにくいのには理由があります。そこから話します。
なぜ分かりにくいのか
いろいろな分野で使われています。 オーディオのコンポ、機械や製造業の部品、ソフトウェアの構成要素。 分野をまたいで登場して、どこでも「構成要素」という同じ広い意味で通っています。
つまり知らない言葉ではなく、広すぎる言葉です。 聞いたことはあるし意味も何となく分かる。だからこそ、web の文脈で具体的に何を指しているのかが絞れません。
web開発の中でも、意味が二層あります。 デザインの単位としてのコンポーネントと、コードの単位としてのコンポーネント。近いものですが、同じではありません。ここが混ざると話がずれます。
AIが勝手にやってくれるので、意識する機会がない。 「いい感じに作って」と頼めば、AIは適当に分けてくれます。 意識してなくても動くので、曖昧なまま進んでる人も多いのではないでしょうか。 あとから困ることのないように、今のうちにしっかり知識として身につけておきましょう。
答え:繰り返すものに、名前をつけたもの
一行で言うとこれだけです。
サイトの中に同じ見た目のものが何度も出てくるとき、それを一つの部品として切り出して名前をつける。以降はその名前を呼ぶだけで済むようにする。それがコンポーネントです。
料理でいえば、合わせ調味料です。毎回それぞれの調味料を計るのではなく、先に混ぜて名前をつけておく。使うときは「あれを入れる」で済みます。味が毎回同じになるのが、いちばんの効き目です。
大きさは決まっていない
二つ目の分かりにくさがここです。コンポーネントには「このくらいの大きさのもの」という決まりがありません。
ボタン一つもコンポーネントです。そのボタンを含んだカードもコンポーネントです。カードを並べたセクションも、それを積んだページ全体もコンポーネントと呼ばれます。
ボタン
└ を含んだカード
└ を並べたセクション
└ を積んだページ
入れ子になっていて、どの階層も同じ言葉です。だから「コンポーネントに分けて」と言われても、ボタンの粒度の話なのかページの粒度の話なのか分かりません。
慣れれば困りません。ただ最初のうちは、どの大きさの話なのかを確認するといいです。ボタンをまとめる作業とページを分割する作業では、やることがまったく違います。
そして中身は見た目だけではありません。押したら開く、入力を受け取る、読み込み中は灰色になる。振る舞いも一緒に閉じ込められます。
分けると何が起きるか
抽象的な話を続けても意味がないので、自分が実際にやったものを出します。
このサイトには記事のページがあります。そして管理画面には、公開前に見た目を確認するプレビューがあります。この二つは、同じ見た目で表示されないと意味がありません。
最初はそれぞれ別に書こうとしました。やめました。別に書くと、片方を直したときにもう片方がズレます。しかもズレたことに気づけません。 プレビューで確認して公開したのに、本番だけ崩れている。いちばん起きてほしくない事故です。
なので記事の見た目を一つの部品に切り出して、公開ページとプレビューの両方がそれを呼ぶようにしました。同じものを呼んでいるので、定義上ズレません。
ここが大事なところです。コンポーネントに分ける理由は、コードの重複を減らすことではありません。ズレる余地を消すことです。重複が減るのは、その副産物です。
一つの部品に、二つの状態を持たせる
もう一つ実例を出します。
いま作っているサイトのテンプレートには、写真を入れる枠があります。買った人が自分の写真に差し替える前提なので、最初は写真が入っていません。
そこで、こういう部品を作りました。写真を渡せば写真を表示する。渡さなければ、斜線の入った枠と「ここに16:9の写真を入れてください」という案内を表示する。
画像あり → 写真を表示
画像なし → 斜線の枠と、寸法の案内を表示
買った人は、写真を用意して渡すだけで済みます。 コードを書き換える必要がありません。分岐は部品の中に隠れているので、外からは同じ呼び方で使えます。
「状態によって見た目が変わる」ものは、コンポーネントにする価値が高いです。外から見た使い方が一つで済むからです。
分けないほうがいいとき
ここが本題です。ほとんどの記事は「分けましょう」しか言いませんが、分けない判断のほうが難しいです。
同じサイトのテンプレートで、私は逆をやりました。ページの文章を、全部一つのファイルにベタ書きにしています。 見出しも本文も、細かく部品に分けていません。
理由は、買った人が編集するからです。
部品に細かく分けると、コードは整います。ただし直したい一文を探すのに、ファイルを何枚も開くことになります。初めて触る人には、それが壁になります。全部が一枚に書いてあれば、上から読んで、見つけて、書き換えるだけで済みます。
つまり、こういうことです。
抽象化は、読み手のためではなく作り手のためのものです。自分が何度も直す場所なら分けたほうが速い。他人が一度だけ直す場所なら、分けないほうが親切です。
分けると必ず良くなる、という話ではありません。誰が、何回、どこを直すのかで答えが変わります。
いつ分けるかの判断
私が使っている基準は4つです。
1. ズレたら困るか。 二箇所以上で同じ見た目を保ちたいなら、分けます。これがいちばん強い理由です。
2. 二回目が出てきたか。 一回目では分けません。二回目で分けます。一度しか使わないものを先に部品にすると、たいてい形が合わなくなって作り直します。
3. 中に動きや状態があるか。 開閉する、入力を受ける、読み込み中の表示が変わる。こういうものは中に閉じ込めたほうが扱いやすくなります。
4. 誰が直すのか。 自分だけが触るなら分けてよい。他人が触る前提なら、探しやすさを優先します。
迷ったら分けないでいいと思います。あとから分けるのは簡単ですが、分けすぎたものを戻すのは面倒です。
AIへの指示の出し方
ここまで分かっていると、頼み方が変わります。
AIは「コンポーネントに分けて」と言えば分けてくれます。ただ、どう分けるかはAIが勝手に決めます。 そして分け方はサイトの育ち方を左右します。
なので、理由を添えて頼みます。
「この3箇所のボタンは同じ見た目にしたいので、一つの部品にまとめて。」
「この画像の枠は、画像が無いときは案内を出す形にして。呼び方は変えずに。」
「このページは購入者が編集するので、文章は分けずに一つのファイルに置いて。」
一行目は「ズレたら困る」、二行目は「状態を中に閉じ込める」、三行目は「他人が直す」。さきほどの基準がそのまま指示になっています。
コマンドを覚える必要はありません。何のために分けるのかを言えれば、あとはAIが形にします。
まとめ
- 分かりにくいのは、知らない言葉ではなく広すぎる言葉だから
- 繰り返すものに名前をつけたもの。それだけ
- 大きさは決まっていない。 ボタンもページもコンポーネント。入れ子になる
- 分ける理由は重複を減らすことではなく、ズレる余地を消すこと
- 抽象化は作り手のためのもの。他人が一度だけ直す場所は、分けないほうが親切
- 迷ったら分けない。あとから分けるのは簡単