T-CREATOR

htmx × Express/Node.js 高速セットアップ:テンプレ・部分テンプレ構成の定石

htmx × Express/Node.js 高速セットアップ:テンプレ・部分テンプレ構成の定石

モダン Web 開発において、フロントエンド技術の複雑化は年々加速しています。React、Vue.js、Angular などの高機能なフレームワークは確かに強力ですが、その反面、設定の複雑さやバンドルサイズの増大、学習コストの高さといった課題も抱えています。

そこで注目されているのが htmx です。htmx は「HTML over the wire」というシンプルなコンセプトで、従来の HTML に動的な機能を追加できる軽量なライブラリです。特に Express/Node.js との組み合わせでは、驚くほど効率的な開発体験を実現できます。

本記事では、htmx × Express/Node.js による高速セットアップ手法と、実用的なテンプレート・部分テンプレート構成の定石をご紹介します。複雑なビルドプロセスや大量の依存関係に疲れた開発者の皆様に、シンプルで効率的な開発手法をお届けいたします。

背景

従来の SPA 開発における課題

モダン Web アプリケーション開発では、React、Vue.js、Angular といったシングルページアプリケーション(SPA)フレームワークが主流となっています。しかし、これらの技術には以下のような課題があります。

学習コストの高さ

  • 複雑な状態管理ライブラリ(Redux、Vuex、NgRx など)の習得が必要
  • JSX、TypeScript、各種プリプロセッサの知識が必須
  • ビルドツール(Webpack、Vite、Rollup など)の設定に時間を要する

開発環境の複雑化

  • 数百から数千の npm パッケージ依存
  • バンドルサイズの増大によるパフォーマンス問題
  • ホットリロードやデバッグ環境の構築に時間がかかる

保守性の問題

  • コンポーネント間の依存関係が複雑化
  • 状態管理の分散により、バグの原因特定が困難
  • フレームワークのバージョンアップ時の破壊的変更への対応

下図は、従来の SPA 開発における複雑な依存関係を示しています。

mermaidflowchart TD
  app["Webアプリケーション"]
  app --> framework["SPAフレームワーク<br/>(React/Vue/Angular)"]
  app --> state["状態管理<br/>(Redux/Vuex/NgRx)"]
  app --> router["ルーティング<br/>(React Router/Vue Router)"]

  framework --> bundler["バンドルツール<br/>(Webpack/Vite)"]
  framework --> transpiler["トランスパイラ<br/>(Babel/TypeScript)"]
  framework --> preprocessor["プリプロセッサ<br/>(Sass/PostCSS)"]

  bundler --> deps["数百〜数千の<br/>npm依存関係"]
  transpiler --> config1["複雑な設定ファイル"]
  preprocessor --> config2["追加設定ファイル"]

このように、従来の SPA 開発では多くのツールや概念を組み合わせる必要があり、プロジェクトの立ち上げだけでも相当な時間と労力を要します。

htmx が解決するフロントエンド開発の複雑性

htmxは、この複雑化したフロントエンド開発に対する画期的なアプローチを提供します。

シンプルな思想 htmx の核となる思想は「HTML over the wire」です。サーバーから HTML フラグメントを受け取り、DOM 操作によってページを更新するという、Web 本来のシンプルな仕組みを活用します。

最小限の学習コスト

  • 新しいプログラミング言語や複雑な概念の習得が不要
  • HTML の属性を追加するだけで動的な機能を実現
  • JavaScript の知識は最小限で済む

軽量性

  • htmx ライブラリ自体は約 14KB(gzip 圧縮時)
  • 外部依存関係なし
  • CDN から直接読み込み可能

強力な機能

  • AJAX、WebSocket、Server-Sent Events のサポート
  • CSS Transition、アニメーション効果の組み込み
  • プログレッシブエンハンスメントの自然な実現

Express/Node.js との相性の良さ

Express/Node.js と htmx の組み合わせは、以下の理由で非常に効果的です。

統一された開発言語

  • フロントエンドとバックエンドの両方で JavaScript を使用
  • チーム内での技術スタック統一が容易
  • コードの共有や再利用がしやすい

豊富なテンプレートエンジン選択肢

  • EJS、Handlebars、Pug、Mustache など多数の選択肢
  • サーバーサイドレンダリングによる SEO 効果
  • 初期表示速度の向上

エコシステムの成熟度

  • npm パッケージの豊富さ
  • 長年の実績による安定性
  • 大規模なコミュニティサポート

下図は、htmx × Express の構成における情報フローを示しています。

mermaidflowchart LR
  browser["ブラウザ"] -->|"htmx属性付きHTML<br/>リクエスト"| express["Express.js<br/>サーバー"]
  express -->|"HTMLフラグメント<br/>レスポンス"| browser
  express --> template["テンプレート<br/>エンジン"]
  express --> logic["ビジネス<br/>ロジック"]
  express --> db[("データベース")]

  template --> partial["部分テンプレート"]
  logic --> api["API処理"]

この構成により、サーバーサイドで HTML を生成し、htmx がクライアントサイドで必要な部分のみを動的に更新する、効率的なアーキテクチャを実現できます。

課題

htmx × Express/Node.js の組み合わせは多くのメリットを提供しますが、実際の開発において以下のような課題に直面することがあります。

テンプレート管理の複雑化

テンプレートファイルの散在 プロジェクトが成長するにつれて、テンプレートファイルが様々なディレクトリに分散し、管理が困難になります。

  • レイアウトテンプレート、ページテンプレート、部分テンプレートが混在
  • ファイルの命名規則が統一されていない
  • テンプレート間の依存関係が不明確

再利用性の低下 適切な設計がされていないと、同様の UI コンポーネントが重複して作成されてしまいます。

  • 類似した HTML コードの重複
  • スタイルやスクリプトの一貫性の欠如
  • 保守時の修正コストの増大

部分テンプレートの効率的な構成方法

粒度の調整が困難 部分テンプレートをどの程度の粒度で分割するかは、開発効率に大きく影響します。

  • 細かすぎる分割:ファイル数の増加、管理コストの上昇
  • 粗すぎる分割:再利用性の低下、柔軟性の欠如
  • htmx のリクエスト単位との整合性

データ受け渡しの複雑化 部分テンプレート間でのデータの受け渡しが煩雑になることがあります。

  • グローバル変数への依存
  • テンプレートエンジンのコンテキスト管理
  • 型安全性の確保の困難さ

開発環境のセットアップ時間

依存関係の選定 Express.js アプリケーションには多くの選択肢があり、適切な組み合わせを見つけるのに時間がかかります。

必要な依存関係の例:

分類選択肢特徴
テンプレートエンジンEJS, Handlebars, Pug記法や機能が大きく異なる
ミドルウェアbody-parser, cors, helmetセキュリティや機能要件による選択
開発ツールnodemon, concurrently開発効率に直結
CSS 処理Sass, PostCSS, Tailwindスタイリング戦略による選択

設定ファイルの複雑化 プロジェクトが成長すると、設定ファイルが複雑になり、新しいメンバーの参入障壁となります。

  • Express.js の設定
  • テンプレートエンジンの設定
  • 開発ツールの設定
  • ビルドプロセスの設定

下図は、一般的な Express + htmx プロジェクトで発生する課題の関係性を示しています。

mermaidflowchart TD
  project["プロジェクト開始"] --> setup["環境セットアップ"]
  setup --> template_choice["テンプレートエンジン選択"]
  setup --> middleware["ミドルウェア選択"]

  template_choice --> file_structure["ファイル構造設計"]
  file_structure --> template_issue["テンプレート管理課題"]
  template_issue --> scattered["ファイル散在"]
  template_issue --> duplication["コード重複"]

  middleware --> config_complexity["設定複雑化"]
  config_complexity --> onboarding["新メンバー参入障壁"]

  scattered --> maintenance["保守コスト増大"]
  duplication --> maintenance
  onboarding --> development_delay["開発速度低下"]

これらの課題を解決するためには、体系的なアプローチと実証済みのベストプラクティスが必要です。

解決策

前章で述べた課題を解決するために、htmx × Express/Node.js における効率的な開発手法をご紹介します。

htmx × Express の最適な構成パターン

レイヤー分離アーキテクチャ プロジェクトの保守性と拡張性を確保するため、以下の 3 層構造を推奨します。

mermaidflowchart TD
  presentation["プレゼンテーション層"] --> business["ビジネスロジック層"]
  business --> data["データアクセス層"]

  presentation --> routes["ルート定義"]
  presentation --> templates["テンプレート"]
  presentation --> htmx_handlers["htmxハンドラー"]

  business --> services["サービス"]
  business --> validators["バリデーション"]

  data --> models["モデル"]
  data --> repositories["リポジトリ"]

推奨ディレクトリ構造 効率的な開発とメンテナンスを実現するディレクトリ構成をご提案します。

textproject-root/
├── src/
│   ├── routes/           # ルート定義
│   ├── services/         # ビジネスロジック
│   ├── models/           # データモデル
│   └── middleware/       # カスタムミドルウェア
├── views/
│   ├── layouts/          # レイアウトテンプレート
│   ├── pages/            # ページテンプレート
│   ├── partials/         # 部分テンプレート
│   └── components/       # 再利用可能コンポーネント
├── public/
│   ├── css/
│   ├── js/
│   └── assets/
└── tests/

テンプレートエンジンの選択と設定

EJS の採用理由とメリット 多くのテンプレートエンジンの中から、EJS を推奨する理由をご説明します。

学習コストの低さ

  • HTML に JavaScript を埋め込む直感的な記法
  • 既存の HTML 知識を活用可能
  • デバッグが容易

htmx との相性

  • HTML フラグメントの生成が簡単
  • 条件分岐やループ処理が直感的
  • データバインディングが分かりやすい

設定例:

javascript// app.js - EJS設定
const express = require('express');
const path = require('path');

const app = express();

// ビューエンジンとしてEJSを設定
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// パーシャル(部分テンプレート)の設定
app.locals.partials = {
  header: 'partials/header',
  footer: 'partials/footer',
  nav: 'partials/navigation',
};

EJS 設定のベストプラクティス

javascript// 本番環境でのキャッシュ有効化
if (process.env.NODE_ENV === 'production') {
  app.set('view cache', true);
}

// 共通データの設定
app.locals.siteName = 'My App';
app.locals.version = process.env.APP_VERSION || '1.0.0';

// htmx用のヘルパー関数
app.locals.htmxAttributes = function (options = {}) {
  const attrs = [];
  if (options.get) attrs.push(`hx-get="${options.get}"`);
  if (options.post) attrs.push(`hx-post="${options.post}"`);
  if (options.target)
    attrs.push(`hx-target="${options.target}"`);
  if (options.swap) attrs.push(`hx-swap="${options.swap}"`);
  return attrs.join(' ');
};

部分テンプレートの設計指針

コンポーネント指向設計 部分テンプレートを再利用可能なコンポーネントとして設計します。

設計原則:

原則説明
単一責任1 つのコンポーネントは 1 つの機能のみユーザーカード、商品リスト
疎結合外部データに依存しない設計プロパティによるデータ受け渡し
再利用性複数の場所で利用可能汎用的なフォーム要素
自己完結必要なスタイルやスクリプトを含むモーダル、ドロップダウン

htmx 対応の部分テンプレート例

html<!-- views/components/user-card.ejs -->
<div class="user-card" id="user-<%= user.id %>">
  <img src="<%= user.avatar %>" alt="<%= user.name %>" class="avatar">
  <div class="user-info">
    <h3><%= user.name %></h3>
    <p><%= user.email %></p>
    <button
      <%- htmxAttributes({
        post: `/users/${user.id}/follow`,
        target: `#user-${user.id}`,
        swap: 'outerHTML'
      }) %>
      class="btn btn-primary">
      <%= user.isFollowing ? 'Unfollow' : 'Follow' %>
    </button>
  </div>
</div>

データ渡しのパターン

javascript// routes/users.js - 部分テンプレートへのデータ渡し
app.get('/users/:id/card', (req, res) => {
  const user = getUserById(req.params.id);
  res.render('components/user-card', { user });
});

// レイアウト内での部分テンプレート呼び出し
// views/pages/users.ejs
<div class="users-grid">
  <% users.forEach(user => { %>
    <%- include('../components/user-card', { user }) %>
  <% }) %>
</div>

パフォーマンス最適化 部分テンプレートのパフォーマンス向上のためのテクニックです。

javascript// キャッシュを活用した効率的なレンダリング
const NodeCache = require('node-cache');
const templateCache = new NodeCache({ stdTTL: 600 }); // 10分キャッシュ

app.get('/api/components/:componentName', (req, res) => {
  const cacheKey = `${
    req.params.componentName
  }-${JSON.stringify(req.query)}`;

  let html = templateCache.get(cacheKey);
  if (!html) {
    html = res.render(
      `components/${req.params.componentName}`,
      req.query
    );
    templateCache.set(cacheKey, html);
  }

  res.send(html);
});

下図は、推奨する部分テンプレート構成パターンを示しています。

mermaidflowchart TD
  layout["レイアウト<br/>テンプレート"] --> page["ページ<br/>テンプレート"]
  page --> component1["コンポーネント1<br/>(Header)"]
  page --> component2["コンポーネント2<br/>(Main Content)"]
  page --> component3["コンポーネント3<br/>(Footer)"]

  component2 --> partial1["部分テンプレート1<br/>(User List)"]
  component2 --> partial2["部分テンプレート2<br/>(Product Card)"]

  partial1 --> htmx1["htmx属性<br/>(hx-get, hx-target)"]
  partial2 --> htmx2["htmx属性<br/>(hx-post, hx-swap)"]

この構成により、保守性が高く、htmx との連携が効率的な部分テンプレートシステムを構築できます。

具体例

ここでは、実際に htmx × Express/Node.js プロジェクトを立ち上げ、効率的なテンプレート構成を実装する手順をステップバイステップでご紹介します。

プロジェクト初期セットアップ

ステップ 1: プロジェクト初期化 まず、新しいプロジェクトを作成し、必要な依存関係をインストールします。

bash# プロジェクトディレクトリの作成
mkdir htmx-express-app
cd htmx-express-app

# npm初期化
yarn init -y

ステップ 2: 基本依存関係のインストール 厳選された必要最小限の依存関係をインストールします。

bash# 本番依存関係
yarn add express ejs helmet compression morgan

# 開発依存関係
yarn add -D nodemon concurrently browser-sync

各パッケージの役割を以下の表で説明します。

パッケージ役割必要性
expressWeb フレームワーク必須
ejsテンプレートエンジン必須
helmetセキュリティヘッダー推奨
compressionレスポンス圧縮パフォーマンス向上
morganログ記録デバッグ支援
nodemon開発サーバー開発効率
concurrently並行実行開発効率
browser-syncライブリロード開発効率

ステップ 3: package.json スクリプトの設定 開発とビルドのスクリプトを効率的に構成します。

json{
  "scripts": {
    "start": "node src/app.js",
    "dev": "concurrently \"nodemon src/app.js\" \"browser-sync start --proxy localhost:3000 --files 'views/**/*' 'public/**/*'\"",
    "test": "echo 'テスト未実装' && exit 0"
  }
}

基本テンプレート構成

ステップ 4: ディレクトリ構造の作成 推奨ディレクトリ構造を作成します。

bash# ディレクトリ構造の作成
mkdir -p src/{routes,services,middleware}
mkdir -p views/{layouts,pages,partials,components}
mkdir -p public/{css,js,assets}
mkdir tests

ステップ 5: Express.js アプリケーションの基本設定 効率的な設定ファイルを作成します。

javascript// src/app.js - メインアプリケーション
const express = require('express');
const path = require('path');
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');

const app = express();
const PORT = process.env.PORT || 3000;

// セキュリティとパフォーマンス
app.use(
  helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: [
          "'self'",
          "'unsafe-inline'",
          'https://unpkg.com',
        ],
        styleSrc: ["'self'", "'unsafe-inline'"],
      },
    },
  })
);
app.use(compression());
app.use(morgan('combined'));

// 静的ファイルの配信
app.use(express.static(path.join(__dirname, '../public')));

// body parser
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

ステップ 6: EJS 設定と htmx ヘルパー テンプレートエンジンの設定と htmx 用ヘルパー関数を実装します。

javascript// EJSテンプレートエンジンの設定
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '../views'));

// 本番環境でのビューキャッシュ
if (process.env.NODE_ENV === 'production') {
  app.set('view cache', true);
}

// グローバル変数とヘルパー関数
app.locals.siteName = 'HTMX Express App';
app.locals.currentYear = new Date().getFullYear();

// htmx属性生成ヘルパー
app.locals.htmx = function (options = {}) {
  const attributes = [];

  // HTTP メソッド
  if (options.get)
    attributes.push(`hx-get="${options.get}"`);
  if (options.post)
    attributes.push(`hx-post="${options.post}"`);
  if (options.put)
    attributes.push(`hx-put="${options.put}"`);
  if (options.delete)
    attributes.push(`hx-delete="${options.delete}"`);

  // ターゲットとスワップ
  if (options.target)
    attributes.push(`hx-target="${options.target}"`);
  if (options.swap)
    attributes.push(`hx-swap="${options.swap}"`);

  // 追加オプション
  if (options.trigger)
    attributes.push(`hx-trigger="${options.trigger}"`);
  if (options.confirm)
    attributes.push(`hx-confirm="${options.confirm}"`);
  if (options.indicator)
    attributes.push(`hx-indicator="${options.indicator}"`);

  return attributes.join(' ');
};

部分テンプレート実装

ステップ 7: ベースレイアウトテンプレート 共通レイアウトを定義します。

html<!-- views/layouts/base.ejs -->
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>
      <%= typeof title !== 'undefined' ? title + ' - ' : ''
      %><%= siteName %>
    </title>
    <link rel="stylesheet" href="/css/main.css" />
    <script src="https://unpkg.com/htmx.org@1.9.6"></script>
  </head>
  <body>
    <%- include('../partials/header') %>

    <main class="main-content"><%- body %></main>

    <%- include('../partials/footer') %>

    <script src="/js/main.js"></script>
  </body>
</html>

ステップ 8: 再利用可能なコンポーネント 汎用的な UI コンポーネントを作成します。

html<!-- views/components/card.ejs -->
<div class="card <%= className || '' %>" <% if (id) { %>
  id="<%= id %>"<% } %>> <% if (header) { %>
  <div class="card-header">
    <h3><%= header %></h3>
  </div>
  <% } %>

  <div class="card-body"><%- content %></div>

  <% if (actions && actions.length > 0) { %>
  <div class="card-actions">
    <% actions.forEach(action => { %>
    <button
      class="btn <%= action.class || 'btn-primary' %>"
      <%-
      htmx(action.htmx
      ||
      {})
      %
    >
      <% if (action.confirm) { %>hx-confirm="<%=
      action.confirm %>"<% } %> > <%= action.label %>
    </button>
    <% }) %>
  </div>
  <% } %>
</div>

ステップ 9: 動的リストコンポーネント htmx を活用した動的なリストコンポーネントを実装します。

html<!-- views/components/task-list.ejs -->
<div class="task-list" id="task-list">
  <div class="task-list-header">
    <h2>タスク一覧</h2>
    <button
      class="btn btn-primary"
      <%- htmx({
        get: '/tasks/new-form',
        target: '#new-task-form',
        swap: 'innerHTML'
      }) %>
    >
      新しいタスク
    </button>
  </div>

  <div id="new-task-form" class="new-task-form"></div>

  <ul class="task-items">
    <% if (tasks && tasks.length > 0) { %>
      <% tasks.forEach(task => { %>
        <%- include('task-item', { task }) %>
      <% }) %>
    <% } else { %>
      <li class="empty-state">まだタスクがありません</li>
    <% } %>
  </ul>
</div>

htmx イベント処理

ステップ 10: サーバーサイドルート実装 htmx リクエストに対応するルートを実装します。

javascript// src/routes/tasks.js
const express = require('express');
const router = express.Router();

// タスク一覧表示
router.get('/', (req, res) => {
  const tasks = getTasks(); // データベースから取得
  res.render('pages/tasks', { tasks, title: 'タスク管理' });
});

// 新規タスクフォーム(部分テンプレート)
router.get('/new-form', (req, res) => {
  res.render('components/task-form', {
    task: null,
    action: '/tasks',
    method: 'POST',
  });
});

// タスク作成(htmxリクエスト)
router.post('/', (req, res) => {
  const newTask = createTask(req.body);

  // htmxリクエストの場合は部分テンプレートのみ返す
  if (req.headers['hx-request']) {
    res.render('components/task-item', { task: newTask });
  } else {
    res.redirect('/tasks');
  }
});

// タスク削除(htmxリクエスト)
router.delete('/:id', (req, res) => {
  deleteTask(req.params.id);

  if (req.headers['hx-request']) {
    res.status(200).send(''); // 空のレスポンス(要素が削除される)
  } else {
    res.redirect('/tasks');
  }
});

module.exports = router;

ステップ 11: メインアプリケーションでのルート登録

javascript// src/app.js(続き)
const tasksRouter = require('./routes/tasks');

// ルートの登録
app.use('/tasks', tasksRouter);

// ホームページ
app.get('/', (req, res) => {
  res.render('pages/home', { title: 'ホーム' });
});

// サーバー起動
app.listen(PORT, () => {
  console.log(`サーバーがポート${PORT}で起動しました`);
});

下図は、実装した htmx × Express 構成のリクエストフローを示しています。

mermaidsequenceDiagram
  participant Browser as ブラウザ
  participant HTMX as htmx
  participant Express as Express.js
  participant Template as テンプレート

  Browser->>HTMX: ボタンクリック
  HTMX->>Express: AJAX リクエスト<br/>(hx-request ヘッダー付き)
  Express->>Template: 部分テンプレート<br/>レンダリング
  Template-->>Express: HTML フラグメント
  Express-->>HTMX: HTML レスポンス
  HTMX->>Browser: DOM 更新<br/>(指定されたターゲット)

この実装により、ページ全体をリロードすることなく、必要な部分のみを動的に更新する効率的な Web アプリケーションを構築できます。

まとめ

本記事では、htmx × Express/Node.js による高速セットアップ手法と、効率的なテンプレート・部分テンプレート構成について詳しく解説いたしました。

実現できること

開発効率の大幅向上

  • 従来の SPA 開発と比較して、セットアップ時間を大幅に短縮
  • 最小限の依存関係による軽量な開発環境
  • 直感的な HTML 記法による学習コストの削減

保守性の高いアーキテクチャ

  • レイヤー分離による責任の明確化
  • 再利用可能なコンポーネント設計
  • 一貫したディレクトリ構造による可読性の向上

パフォーマンスの最適化

  • 必要な部分のみの動的更新
  • サーバーサイドレンダリングによる SEO 効果
  • 軽量なライブラリによる高速な動作

重要なポイント

本記事で紹介した手法を成功させるための重要なポイントをまとめます。

設計原則の遵守

  1. 単一責任の原則: 各コンポーネントは 1 つの機能のみを担当
  2. 再利用性の確保: 汎用的な部分テンプレートの作成
  3. 疎結合の維持: コンポーネント間の依存関係を最小限に抑制

技術選択の判断基準

  • EJS テンプレートエンジンによる直感的な開発体験
  • Express.js の豊富なエコシステムの活用
  • htmx の軽量性とシンプルさの活用

ベストプラクティスの活用

  • 一貫したファイル命名規則
  • 適切なキャッシュ戦略の実装
  • セキュリティヘッダーの設定

次のステップ

この構成をベースに、さらなる機能拡張を検討される場合は、以下の要素を段階的に追加することをお勧めします。

データベース統合

  • Prisma、Sequelize、Mongoose などの ORM の導入
  • データ検証とサニタイゼーション
  • トランザクション管理

認証・認可システム

  • Passport.js を活用したソーシャル認証
  • JWT Token による API 認証
  • ロールベースアクセス制御(RBAC)

パフォーマンス最適化

  • Redis を活用したセッション管理
  • CDN による静的ファイル配信
  • データベースクエリの最適化

デプロイメント環境

  • Docker コンテナ化
  • CI/CD パイプラインの構築
  • クラウドサービス(AWS、GCP、Azure)への展開

監視・ログ管理

  • アプリケーションメトリクスの収集
  • エラートラッキングシステムの導入
  • パフォーマンス監視ツールの設定

htmx × Express/Node.js の組み合わせは、モダン Web アプリケーション開発において、シンプルさと効率性を両立できる優れた選択肢です。複雑なフロントエンド技術に疲れた開発者の皆様にとって、この手法が新たな開発体験をもたらすことを願っております。

今後も継続的な学習と実践を通じて、より効率的で保守性の高い Web アプリケーション開発を実現してください。

関連リンク

公式ドキュメント

学習リソース

セキュリティ関連

コミュニティ