フロントエンド技術の全体像と「なぜ必要か」
Web アプリケーションのフロントエンドを構成する技術 — HTML/CSS/JavaScript、React、TypeScript、Remix、Tailwind CSS、Vite — の役割と関係性を体系的に解説します。
まず「フロントエンド」とは
Web アプリケーションは大きく2つの層に分かれます。
ユーザーのブラウザ上で動く部分(画面の見た目、ボタンの動き、入力フォームなど)
サーバー上で動く部分(データベースへの保存、認証チェック、AI 呼び出しなど)
このブログでは Remix というフレームワークが両方を橋渡ししていますが、まずは各技術を順番に説明します。
1HTML / CSS / JavaScript — Web の三大基盤
全てのフロントエンド技術は、最終的にこの3つに変換されてブラウザで実行されます。
| 技術 | 役割 | 例え |
|---|---|---|
| HTML | ページの「構造」を定義 | 建物の骨組み(見出し、本文、ボタン) |
| CSS | ページの「見た目」を定義 | 内装・塗装(色、フォント、余白、レイアウト) |
| JavaScript | ページの「動き」を定義 | 電気設備(ボタンを押したら何かが起こる) |
なぜこれだけでは不十分か?
小さなページなら HTML + CSS + JavaScript を直接書けば十分です。しかし、数十ページ・複数の機能を持つアプリケーションでは:
- HTML が数千行になり、共通部分(ヘッダー、ナビ)の管理が困難
- CSS が衝突する(ある箇所のスタイルが別の箇所に影響)
- JavaScript が複雑化し、バグの追跡が困難
2React — UI を「部品」に分割する
何をするものか
React は Facebook(Meta)が開発した JavaScript ライブラリで、画面を 「コンポーネント」 という再利用可能な部品に分割して組み立てます。
レゴブロックのようなもの
「ヘッダー」ブロック、「記事カード」ブロック、「ボタン」ブロックを個別に作り、それらを組み合わせてページを構築します。
- index.html に全ページの HTML を書く
- ナビ変更 → 全ページを手動修正
- ページ増加 → コードをコピペ
- → バグの温床
<Header />コンポーネントを1つ作る- 全ページで
<Header />と書くだけ - 変更は1箇所だけ → 一貫性を維持
このブログでは、ProblemCard、FeatureRow、StatCard など多くのコンポーネントが使われています。一度定義すれば、データだけ変えて何度でも再利用できます。
3TypeScript — JavaScript に「型」を加える
何をするものか
TypeScript は Microsoft が開発した言語で、JavaScript に 「型(かた)」 を追加します。「型」とは変数やデータの「種類」を明示することです。
// JavaScript(型なし)— 何でも入る
let count = 5;
count = "hello"; // エラーにならない!でも後で計算しようとしたらバグ
// TypeScript(型あり)— 数値しか入らない
let count: number = 5;
count = "hello"; // コンパイル時にエラー!実行前にバグ発見なぜ必要か
実行する前に、コードを書いた時点でミスを検出
変数の中身がわかるので、IDE が候補を自動表示
関数名や変数名を変更しても、影響箇所を自動検出
このブログでの活用
データベースのテーブル定義(Drizzle ORM のスキーマ)から API のレスポンス型、画面のコンポーネントのプロパティまで、全て TypeScript の型で繋がっています。「DB のカラム名をタイポしたら画面が壊れる」というバグを コードを書いた瞬間に 検出できます。
4Remix — フロントとバックを繋ぐフレームワーク
「フレームワーク」とは
アプリケーションの 「作り方の枠組み」 を提供するものです。「こういうルールでファイルを配置し、こういうパターンでコードを書けば、自動的に動くようにしてあげます」という仕組みです。
Remix が解決する課題
課題1: ページの URL とファイルの対応(ルーティング)
app/routes/admin.presentation.tsx → /admin/presentation
app/routes/search.tsx → /search
app/routes/posts.$slug.tsx → /posts/any-article-slugファイルを作るだけで URL が自動的に決まります。手動で「この URL に来たらこのファイルを表示」という設定を書く必要がありません。
課題2: データの取得と画面への受け渡し
// Loader = ページ表示前にサーバーでデータを取得する関数
export async function loader() {
const posts = await db.select().from(posts); // DBから記事を取得
return { posts }; // 画面に渡す
}
// コンポーネント = ブラウザで表示される画面
export default function Page() {
const { posts } = useLoaderData(); // Loaderのデータを受け取る
return <div>{posts.map(p => <h2>{p.title}</h2>)}</div>;
}課題3: SSR(サーバーサイドレンダリング)
ブラウザが空の HTML を受信 → JavaScript をダウンロード → 実行 → やっと画面表示(遅い、SEO に不利)
サーバーが完成した HTML を生成して送信 → すぐ表示される(速い、Google にも記事内容が見える)
なぜ Remix なのか(他の選択肢との比較)
| フレームワーク | 特徴 | このブログで使わない理由 |
|---|---|---|
| Next.js | 最も人気 | Cloudflare Workers での動作が不安定。Vercel 前提の設計 |
| Nuxt | Vue.js ベース | React エコシステムではない |
| Remix | 採用 ✓ | Workers ネイティブ対応、Web 標準ベースの設計 |
5Tailwind CSS — スタイリングの効率化
従来の CSS の課題
/* styles.css — 別ファイルで管理 */
.card { background: white; border-radius: 12px; padding: 24px; }
.card-title { font-size: 18px; font-weight: bold; }
/* → ファイルが数百行に膨れ、どのスタイルがどこで使われているか不明に */
/* → .card を変更したら、意図しない場所のカードも変わってしまう */Tailwind のアプローチ
// HTML/JSX の中に直接スタイルを書く
<div className="rounded-2xl bg-white p-6 shadow-sm">
<h3 className="text-lg font-bold">タイトル</h3>
</div>| クラス名 | 意味 |
|---|---|
| rounded-2xl | 角を丸くする |
| bg-white | 背景色を白に |
| p-6 | 内側の余白(padding)を 24px |
| shadow-sm | 小さい影をつける |
| text-lg | 文字サイズを大きめに |
| font-bold | 太字 |
なぜ Tailwind なのか
スタイルがコンポーネントの中で完結し、「このスタイルどこで使ってる?」が明白
クラス名が標準化されているため、自分で名前を考える必要がない
使っていないクラスは自動削除され、CSS ファイルが最小化される
CSS-in-JS はサーバーで追加処理が必要だが、Tailwind はビルド時に完結
6Vite — 開発体験の高速化
「ビルドツール」とは
TypeScript や React のコードは、そのままではブラウザで実行できません。 ビルドツールがこれらを変換・結合して、ブラウザで動く HTML/CSS/JavaScript にします。
開発中の課題
コード変更 → ビルド → ブラウザ再読み込み → 確認 のサイクルが遅いと開発効率が激落ちします。
Vite の解決策
コードを保存した瞬間に、ブラウザがページ全体を再読み込みせず変更部分だけを即座に更新
従来のツール(Webpack)が全ファイルをまとめてからサーバー起動するのに対し、Vite は必要なファイルだけをその場で処理
不要なコードの除去(Tree Shaking)、ファイル分割(コード分割)を自動実行