MicroCMSとViteで作るかんたん静的サイト

MicroCMS × Vite × 11tyでAPIデータの取得とHTMLの生成を行います。
2023.10.11

この記事では、ヘッドレスCMSを使ってHTMLコンテンツを生成する手順を紹介します。
前回の記事(MicroCMSと11tyで作るかんたん静的サイト)ではAPIデータの取得とHTMLの生成のみを行いましたが、今回はSassを使うためにビルドツールであるViteを導入して、より実制作に近い環境での検証をします。

ビルドツールであればGulpやWebpack等の選択肢もありましたが、Viteの設定が非常に簡便であるという噂を聞いたので試してみることにしました。

対象ユーザーのスキル
  • HTML
  • CSS
  • JS
  • GulpやWebpack等のビルドツール利用経験

各ツールの役割

  • MicroCMS:ヘッドレスCMS。コンテンツのデータを登録できる、APIを提供している。
  • 11ty:ヘッドレスCMSのAPIからコンテンツを取得できる静的サイトジェネレーターで、HTMLを出力することができる。複数のテンプレート形式に対応している。
  • Vite:11tyだけではCSSとJSのビルドはできないので、そこを補うために11tyと組み合わせて使う。

検証

検証時の環境
  • macOS Ventura バージョン: 13.6
  • node: v18.16.0
  • Google Chrome バージョン: 117.0.5938.149

Viteプロジェクトの作成

Viteで新規プロジェクトを作成します。
参考サイト:最初の Vite プロジェクトを生成する

npm create vite@latest
✔ Project name: … vite-project
✔ Select a framework: › Vanilla
✔ Select a variant: › JavaScript

vite-projectディレクトリが作成され、package.jsonも生成されました。

package.json

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "vite": "^4.4.5"
  }
}

プロジェクトのルートに移動して動作を確認します。

cd vite-project
npm install
npm run dev

Hello Viteが表示されました。http://localhost:5173/

挙動の確認ができたのでサンプルファイルは削除しておきます。 package.json、node_modulesだけ残します。

rm -r public index.html style.css main.js counter.js javascript.svg

Sassの導入

まずはCSSが利用できることを確認してみます。
HTMLファイルを作成します。

cat << EOF > index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Viteのテストだよ</title>
  <link href="./style.css" rel="stylesheet">
</head>

<body>
  <h1>見出し</h1>
  <p>本文</p>
</body>
</html>
EOF

CSSファイルを作成します。

cat << EOF > style.css
body {
  color: #800000;
  background: #C0FFEE;
}
EOF
npm run dev

作成したファイルが表示されました。http://localhost:5173/

Sassを使いたいのでインストールします。CSSファイルの拡張子をscssに変更します。

npm install --save-dev sass
mv style.css style.scss

package.jsonに追記されました。

package.json

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "sass": "^1.69.2",
    "vite": "^4.4.5"
  }
}

HTMLからの読み込みもscssに変更します。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Viteのテストだよ</title>
  <link href="./style.scss" rel="stylesheet">
</head>

<body>
  <h1>見出し</h1>
  <p>本文</p>
</body>
</html>

Sassの記述に変更するべく、入れ子にしてみます。

style.scss

body {
  background: #C0FFEE;
  h1 {
    color: #800000;
  }
}
npm run dev

問題なく表示されました。http://localhost:5173/

ビルドも試してみます。

npm run build

distディレクトリが生成されました。

tree dist
dist
├── assets
│   └── index-68e16457.css
└── index.html

プラグインの導入

HTMLテンプレートを使ってMicroCMSのAPIを取得したいので、Viteで11tyを扱うためのプラグインをインストールします。
参考サイト:vite-plugin-eleventy

npm install --save-dev vite-plugin-eleventy

vite.config.jsを作成します。

touch vite.config.js

ミニマルの記述で用意しておきます。

vite.config.js

// vite.config.js
export default {
  // 設定オプション
}

参考サイト:vite.config.jsの設定

プラグインを使うために設定ファイルに追記します。

vite.config.js

import { eleventyPlugin } from "vite-plugin-eleventy";

export default {
  plugins: [eleventyPlugin()],
}

参考サイト:Vite プラグインの追加

11tyのプラグインを追加できたので、HTMLテンプレートとデータファイルを用意して動作確認します。
今回は(今回も)お気に入りコーヒーのリストを作成してみます。

cat << EOF > index.njk
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Viteのテストだよ</title>
  <link href="./style.scss" rel="stylesheet">
</head>

<body>
  <h1>お気に入りコーヒー</h1>
  <ul>
  {%- for content in contents %}
    <li>
      {{ content.name }} | {{ content.shop }}
    </li>
  {%- endfor %}
  </ul>
</body>
</html>
EOF
cat << EOF > index.json
{
  "contents": [
    {
      "name": "スターバックスラテ",
      "shop": "スターバックス"
    },
    {
      "name": "Flat White",
      "shop": "小川珈琲"
    }
  ]
}
EOF

参考サイト:11ty JSONデータとHTMLの関連付け

index.htmlファイルは使用しないので削除しておきます。

rm index.html

動作確認してみます。

npm run dev

http://localhost:5173/にアクセスします。

JSONデータを読み込んで表示されました。

APIからデータを取得

ローカルに作成したJSONデータと同じ内容のものを、今度はMicroCMSからAPIで取得できるようにします。
MicroCMSの設定方法に関しては前回の記事を参照してください。
参考サイト:MicroCMSにデータを登録 / API-KEYを発行
MicroCMS側の準備ができましたら、MicroCMSからデータをとってくるための環境を整えます。
HTTPリクエストのライブラリnode-fetchと、API-KEYのベタ書きを避けるための環境変数ファイルを利用します。
プロジェクトのルートディレクトリに.envファイルを作成して、MicroCMSから発行されるAPIキーとエンドポイントを設定します。

touch .env

.env

//APIキー
API_KEY = ********************************JNTG

//エンドポイント
ENDPOINT_URL_COFFEE = https://chiezo-test.microcms.io/api/v1/coffee

_dataディレクトリの中にJSファイルを入れるとグローバルデータファイルとして(プロジェクト全体で)使用できるようになります。
参考サイト:11ty JAVASCRIPT DATA FILES

mkdir _data
touch _data/api_coffee.js

api_coffee.js

const fetch = require('node-fetch');
require('dotenv').config();

module.exports = async function() {
  const coffeeDataResponse = await fetch(process.env.ENDPOINT_URL_COFFEE, {
    headers: { "X-MICROCMS-API-KEY": process.env.API_KEY },
  });
  const coffeeData = await coffeeDataResponse.json();
  return coffeeData.contents;
};

dotenvとnode-fetchをインストールして上記の2ファイルを使えるようにします。

npm install --save-dev dotenv node-fetch@2

package.jsonに追記されました。

package.json

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "dotenv": "^16.3.1",
    "node-fetch": "^2.7.0",
    "sass": "^1.69.0",
    "vite": "^4.4.5",
    "vite-plugin-eleventy": "^0.3.1"
  }
}

このままビルドしてしまうとローカルのJSONデータを読みにいってしまうので、HTMLテンプレート側も書き換えます。 for content in contentsfor content in api_coffeeにします。

index.njk

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Viteのテストだよ</title>
  <link href="./style.scss" rel="stylesheet">
</head>

<body>
  <h1>お気に入りコーヒー</h1>
  <ul>
  {%- for content in api_coffee %}
    <li>
      {{ content.name }} | {{ content.shop }}
    </li>
  {%- endfor %}
  </ul>
</body>
</html>
npm run dev

エラーが出てしまいました。

error when starting dev server:
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/chiezo/Web/vite-11ty_minimum2/vite-project/_data/api_coffee.js from /Users/chiezo/Web/vite-11ty_minimum2/vite-project/node_modules/@11ty/eleventy/src/TemplateData.js not supported.
api_coffee.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead rename api_coffee.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /Users/chiezo/Web/vite-11ty_minimum2/vite-project/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

調べてみたところ、_data/api_coffee.jsの拡張子をcjsに変更する必要がありそうです。
参考サイト:Vite の CJS Node API は非推奨に

• ESM をデフォルトとして設定し、必要であれば CJS にオプトインする: プロジェクトの package.json に "type": "module" を追加します。すべての *.js ファイルは ESM として解釈されるようになり、ESM 構文を使用する必要があります。ファイルの拡張子を .cjs にリネームすることで、CJS を使用し続けることができます。

_data/api_coffee.js → api_coffee.cjs 拡張子をcjsに変えて再度開発環境を実行します。

mv ./_data/api_coffee.js ./_data/api_coffee.cjs
npm run dev

無事に動きました。

ビルドも試します。

npm run build

HTMLファイルが生成されました。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Viteのテストだよ</title>
  
  <link rel="stylesheet" href="/assets/index-2afcf51e.css">
</head>

<body>
  <h1>お気に入りコーヒー</h1>
  <ul>
    <li>
      スターバックスラテ | スターバックス
    </li>
    <li>
      Flat White | 小川珈琲
    </li>
  </ul>
</body>
</html>

ビルドした際の生成先はこちらになります。

tree dist
dist
├── assets
│   └── index-2afcf51e.css
└── index.html

これで、MicroCMSのAPIからデータの取得とSassを使用してのレイアウトができるようになりました。非常に少ない設定で環境を構築することができました、おわり。