実践、Jamstackサイト制作 第1回 静的サイトジェネレーターによるHTML生成

Jamstackでのサイト制作にはいくつかのルールがありますが、実際はどのように進めていけばよいのでしょうか。まずは静的なHTMLを生成するところから始めてみましょう。

発行

著者 中野 祐人 Jamstackエンジニア
実践、Jamstackサイト制作 シリーズの記事一覧

はじめに

ピクセルグリッドでは以前からJamstackの仕組みや概念、セキュリティ問題などについて解説してきました。

このシリーズでは、Jamstack実践編として、初歩的なWebサイトの制作からJamstackでのサイト制作までの過程を順を追って解説していくことで、Jamstackをきちんと学んでいきます。

上記の関連記事「いまからわかるJamstack」にもありますが、Jamstackでのサイト制作には、次の4つのルールがあります。

  1. サーバーサイドでHTMLを作らず、静的なHTMLにする
  2. 静的サイトジェネレーターで静的なHTMLを生成し、その過程でできるだけデータを埋め込んでおく
  3. 動的なデータはAPIを通じてアクセスし、完全に分離する
  4. Jamstack向けのホスティングサービスを使う

このJamstackのルールに則ったサイト制作は、具体的にはどのように進めていけばよいのかを見ていきましょう。まず今回は、次の順で解説していきます。

  • STEP1 htmlファイルを作成する
  • STEP2 静的サイトジェネレーターを使う
  • STEP3 静的ファイルを出力する

htmlファイルを一から自分の手で書くところから、静的サイトジェネレーターを使ってより効率的にサイトを作る方法までです。4つのルールのうち、1と2に該当するところになります。

STEP1 htmlファイルを作成する

Webサイトを作りたい人が、一番初めにすることは、「HTMLを学び、htmlファイルを作成すること」でしょう。

たとえば、以下のようなindex.htmlを作成します。

index.html

<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>Jamstack実践編</title>
  </head>
  <body>
    <p>これは初めて作ったwebサイトです。</p>
  </body>
</html>

そして、そのhtmlファイルをブラウザで開くとページを表示できます。

ローカルで確認している状態ではあるものの、これが一番簡単なWebサイトの作り方でしょう。

STEP2 静的サイトジェネレーターを使う

とはいえ、それなりの規模のWebサイトになってくると、このような方法でWebサイトを作るのには限界が訪れます。

たとえば、多くのWebサイトには共通ヘッダーがありますが、ただ、HTMLをベタ書きしているとそれらのヘッダは新しいページができるごとに、何度も複製されることになります。

以下は、先ほどのサイトに新しくabout.htmlを追加するため、index.htmlにヘッダーを追加した例です。

index.html

<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Jamstack実践編</title>
</head>
<body>
  <header>
    <ul>
      <li>
        <a href="./index.html">top</a>
      </li>
      <li>
        <a href="/about.html">about</a>
      </li>
    </ul>
  </header>
  <p>これは初めて作ったwebサイトです。</p>
</body>
</html>

これに対して、about.htmlも同じヘッダを持つことになります。

about.html

<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Jamstack実践編</title>
</head>
<body>
  <header>
    <ul>
      <li>
        <a href="./index.html">top</a>
      </li>
      <li>
        <a href="./about.html">about</a>
      </li>
    </ul>
  </header>
  <p>Jamstack はwebサイトやwebアプリを作るモダンな方法です。</p>
</body>
</html>

このようにそれぞれのページにヘッダーをベタ書きしていると、何か変更しようとした場合の変更範囲はページの数だけ増えていくことになり、ページが増えれば管理できなくなるでしょう。

このような問題は、静的サイトジェネレーターを導入することで解決できます。

静的サイトジェネレーターを導入し、コンポーネントを切り出す

静的サイトジェネレーターは、開発時にはHTMLをコンポーネントとして管理する機能や同じ要素をループなど、プログラマブルに書ける機能によって効率的にサイトを作ることができ、最終的には静的なhtmlファイルを出力してくれるものです。

これを使うことで、ヘッダーのHTMLを部品として切り出し、それぞれのページではその部品を読み込むというような構造化が可能です。

静的サイトジェネレーターは、EleventyやGatsbyJSなどさまざまなものがありますが、今回はAstroを使った例を解説します。

Astroについて

Astroは、まだバージョンは0.20.12(2021/10/26時点)とベータ版ですが、クライアントサイドのJavaScriptが少ない高速なページを生成するSSGで、生成されるサイトがReactやVue.jsなど、特定のフレームワークありきのものにならないのが特徴です。

まずはじめに、Astroは比較的新しいNode.jsを必要とするのでバージョンを合わせます。筆者は記事執筆時の最新バージョンであった、v16.11.1を使用しました。

利用できるバージョンは、詳しくは公式ドキュメントをご覧ください。

$ node --version  //v16.11.1

Node.jsのバージョンが確認できたら、プロジェクトディレクトリで以下のコマンドを叩くと、いくつか質問され、それに答えるだけで開発環境が整います。

$ npm init astro

このとき、テンプレートを

  • Starter Kit (Generic)
  • Blog
  • Documentation
  • Portfolio

から選択できます。今回はStarter Kit (Generic)を選択しました。

プロジェクトファイルのコピーが正常に終了したら、依存関係をインストールしておきましょう。


$ npm install

プロジェクトファイルが正常にコピーされると、以下のようなディレクトリ構成になっています。

  /
  ├── public/
  │   ├── robots.txt
  │   └── favicon.ico
  ├── src/
  │   ├── components/
  │   │   └── Tour.astro
  │   └── pages/
  │       └── index.astro

  ├── package.json
  └── etc...

Astroでは/src/pages配下においたファイルがそのままページのURLになるので、aboutページを作るため、pages配下にabout.astroファイルを作成します。

中身は先ほど作成したabout.htmlと、ほとんど同じものです。ヘッダーのリンク先を少し変更しました。

about.astro

<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>Jamstack実践編</title>
  </head>
  <body>
    <header>
      <ul>
            <li>
                <a href="./">top</a>
            </li>
            <li>
                <a href="./about">about</a>
            </li>
        </ul>
    </header>
    <p>Jamstack はwebサイトやwebアプリを作るモダンな方法です。</p>
  </body>
</html>

開発環境を立ち上げ、このaboutページを確認してみましょう。

開発環境は以下のコマンドで、デフォルトではhttp://localhost:3000に立ち上がります。

$ npm run dev

aboutページはhttp://localhost:3000/aboutでアクセスできます。

では次に、同じヘッダーをindexページでも使えるように、コンポーネントとして切り出しましょう。

Astroではコンポーネントを/src/components配下に定義するので、/src/components/Header.astroを作成します。

その中身は先ほど作成したabout.astroのheaderタグ部分を切り出したものです。

Header.astro

<header>
  <ul>
        <li>
            <a href="./">top</a>
        </li>
        <li>
            <a href="./about">about</a>
        </li>
    </ul>
</header>

これを、about.astroでは、以下のようにして読み込みます。

about.astro

---
import Header from '../components/Header.astro
---
<html lang="ja">
<body>
  <head>
    <meta charset="UTF-8">
    <title>Jamstack実践編</title>
  </head>
  <Header />
  <p>Jamstack はwebサイトやwebアプリを作るモダンな方法です。</p>
</body>
</html>

最初にimportを使っていることからも想像できるかもしれませんが、astroファイルでは、上部の---の間にJavaScriptやTypeScriptが書けます。TypeScriptを書く際にも特別な設定は必要なく、そのまま書くことができます。

そこでヘッダーを/components/Header.astroからインポートし、テンプレートでは

<Header />

と、呼び出しているわけです。

コンポーネントを使って別ページを作る

Headerコンポーネントができたので、index.astroもHeaderコンポーネントを使って作成できます。

デフォルトで用意されているindex.astroの中身を削除し、最初に作成したindex.htmlと同じ内容のものに変更します。

index.astro

---
import Header from '../components/Header.astro'
---
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>Jamstack実践編</title>
  </head>
  <body>
    <Header />
    <p>これは初めて作ったwebサイトです。</p>
  </body>
</html>

これで、ヘッダーを共通化したindexページとaboutページが作成できました。

このようにして、静的サイトジェネレーターを使えば、効率的に開発できる環境が手に入ります。

STEP3 静的ファイルを出力する

前節で静的サイトジェネレーターは、

開発時にはHTMLをコンポーネントとして管理する機能や同じ要素をループなど、プログラマブルに書ける機能によって効率的にサイトを作ることができ、最終的には静的なhtmlファイルを出力してくれるものです。

と説明しました。その「最終的なhtmlファイル」は、以下のコマンドで出力できます。

$ npm run build

このような、「開発時のファイル、コードを解析し実際にブラウザ上で動作するファイル、コードに変換すること」を、Jamstackでの制作という文脈ではビルドと言います。

プロジェクトルートにはdistディレクトリが生成され、以下のような構成になっています。

  /
  ├── about/
  │   └── index.html
  ├── index.html

  ├── assets/
  ├── style/
  └── etc...

先ほど作った、index.astroをもとにindex.htmlが、about.astroをもとにabout/index.htmlが、きちんと出力されているのがわかるでしょう。

まとめ

今回はhtmlファイルを一から自分の手で書くところから、静的サイトジェネレーターを使ってより効率的にサイトを作る方法を解説しました。

次回は今回作ったサイトを実際に配信し、公開する部分を解説します。