HTML テンプレートエンジン詰め合わせ 11ty/eleventy を使ってみる

## はじめに

本記事では [11ty/eleventy](https://www.11ty.dev/) の紹介と簡単なサンプル作成に留め、SCSS ファイルなどの環境構築については別記事を執筆予定です。

テンプレートエンジンとして Nunjucks を使用しますので、Nunjucks の記法について知見のある方でしたらスムーズに読み進めることができるかと思います。

「Nunjucks？なにそれおいしいの？」という方は以下をご参照ください。
EJS と比較すると独自記法も多いですが、個人的にはかなり使いやすいテンプレートエンジンだと思っています。

[Nunjucks 公式ドキュメント](https://mozilla.github.io/nunjucks/)
[詳解 Nunjucks − Mozilla 謹製テンプレートエンジン](https://qiita.com/toshifumiimanishi/items/d3fd1035697618c3c33b)

**2020.03.29
[静的サイトジェネレーター 11ty/eleventy をもっと使ってみる](https://qiita.com/yuzuru_xa/items/c2148a9ce31f852d8c9a)
を追加しました。こちらではより詳細に11tyの機能についてまとめています。**

**2020.04.18
[11ty/eleventy で CSS / SCSS を扱うために](https://qiita.com/yuzuru_xa/items/5f19aa9815cdfa1e2c3c)
を追加しました。**


## [11ty/eleventy](https://www.11ty.dev/)とは？

[11ty/eleventy](https://www.11ty.dev/)（以下11ty）は **Zach Leatherman** 氏により制作された静的サイトジェネレーターです。
Gatsby.js や Nuxt.js など、JS フレームワークを静的サイトジェネレータとして使用するのとは異なり、HTML のテンプレートエンジンをベースとして静的サイトを構築することができます。
11ty での静的ページ生成には Pug や EJS, Nunjucks などのテンプレートエンジンからマークダウンまで幅広く対応しており、下記テンプレートエンジンを使用されたことのある方はかなり導入しやすいのではないかと思います。

本記事では [Nunjucks](https://mozilla.github.io/nunjucks/) とマークダウンファイルをベースに、HTML ファイルを作成していきます。

### Support Language
- HTML（.html）
- Liquid（.liquid）
- EJS（.ejs）
- Markdown（.md）
- Handlebars（.hbs）
- Mustache（.mustache）
- Haml（.haml）
- Pug（.pug）
- Nunjucks（.njk）
- JavaScript（.11ty.js）

以下サイトで他の静的サイトジェネレータとの比較を見ることができます。
[StaticGen](https://www.staticgen.com/)

11ty には **CSS や JS ファイル周りのコンパイル/トランスパイルは含まれていない**ため、この点に関しては自身で環境構築する必要があります。
裏を返せば、**スタイルシートやスクリプトの環境が制限されていないので、何を使用するかはプロジェクトや各々の好みによって自由に変更することができる**ということでもあります。

## 11ty の環境構築

[11ty 公式スタートガイド](https://www.11ty.dev/docs/getting-started/)を辿りながら、ミニマム な11ty プロジェクトの作成から進めていきます。

まずは npm を使用して `@11ty/eleventy `パッケージをインストールします。
このとき、node.js のバージョンは 8 以上である必要があるので注意してください。

> Eleventy is available on npm and requires version 8 of Node.js or higher.

作成するサンプルページは [11ty 公式スタートガイド](https://www.11ty.dev/docs/getting-started/)に則って、適当な場所に空の `eleventy-sample` ディレクトリを用意して進めていきます。

`$ mkdir eleventy-sample`
`$ cd eleventy-sample`

次に package.json の生成と、11ty パッケージのローカルインストールを行います。

`$ npm init -y`
`$ npm install --save-dev @11ty/eleventy`

初期状態では 11ty のコンパイルタスクがないので、package.json の scripts に

`"serve": "eleventy --serve"`

を追加しておきます。

- コンパイルタスク追加後の package.json

```json:package.json
{
  "name": "200225_eleventy_sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "serve": "eleventy --serve"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@11ty/eleventy": "^0.10.0"
  }
}
```

（2020/2/25日現在、11ty のバージョン0.10.0がインストールされます。）

これで 11ty の使用準備が整いました。

### サンプルページの出力

`eleventy_sample` ディレクトリ以下に `index.njk` と `README.md` の二つファイルを追加します。
[11ty 公式スタートガイド](https://www.11ty.dev/docs/getting-started/)のサンプルが寂しかったので若干追加しています。

```html:index.njk
<!doctype html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    <p>Hi</p>
  </body>
</html>
```

```markdown:README.md
# Page header

## Heading

Text Sample
```

前章で package.json に追加した

`$ npm run serve` 

を実行すると、HTML の出力 + ファイル監視タスク が走るようになっています。

デフォルトの設定では `_site` ディレクトリとコンパイル後の HTML ファイルが追加され、ローカルサーバーが立ち上がります。
また、`index.html` と `README/index.html` が `_site/` に作成されていることが確認できるかと思います。
入出力のディレクトリ名は設定ファイルに記述することで変更が可能ですが、こちらは別記事で。

[11ty 公式スタートガイド](https://www.11ty.dev/docs/getting-started/)ベースのサンプル作成は以上です。

が、11ty では各ファイルに YAML 形式の **front-matter** という記法で変数やテンプレートファイルを設定することができます。
本記事では front-matter を使用した変数のセットとテンプレート継承まで紹介します。

## front-matter の使用

front-matter は以下のように `—-` で区切って YAML 形式で記述します。

```
---
pageTitle: Hello 11ty
txt: <p>Hi</p>
---
```

### 変数のセット

front-matter の記述は変数として使用することが可能です。
Nunjucks であれば、マスタッシュ構文で変数を出力することができます。

```html
---
pageTitle: Hello 11ty
txt: <p>Hi</p>
---

<!doctype html>
<html>
  <head>
    <title>{{ pageTitle }}</title>
  </head>
  <body>
    {{ txt | safe }}
  </body>
</html>
```

`{{ pageTitle }}` には front-matter に記述した `Hello 11ty` が表示されます。
また、body 内の `{{ txt | safe }}` には、txt 変数として定義されている `<p>Hi</p>` が safe フィルターによって HTML タグごと出力されます。

### 11ty のテンプレート継承を利用する

front-matter による設定で、拡張子の異なるファイルをテンプレートとして使用することができます。

テンプレートとして以下のような `layout.njk` ファイルを作成します。
テンプレートファイルは `_include` ディレクトリ以下に配置する必要があります。

```html:layout.njk
<!doctype html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    {{ content | safe }}
  </body>
</html>
```

マークダウンファイルから生成される HTML タグは自動エスケープしてほしくないため、Nunjucks の内蔵フィルターである `safe` をつけておきます。
テンプレートとして上記のファイルを使用したい場合、front-matter に YAML 形式で読み込むテンプレートファイルを記述します。

```markdown:README.md
---
layout: layout.njk
---

# Page header

## Heading

Text Sample
```

コンパイルしてみると、 `layout.njk` をベースとして `README/index.html` が変更されているはずです。

### EJS でもテンプレート継承してみる

本来であれば extends はサポートされていない EJS ですが、11ty ではNunjucks と同様テンプレートとしての利用が可能です。

```html:layout.ejs
<!doctype html>
<html>
  <head>
    <title>EJS Template Sample</title>
  </head>
  <body>
    <%- content %>
  </body>
</html>
```

```markdown:README.md
---
layout: layout.ejs
---

# Page header

## Heading

Text Sample
```

`<%- content %>` 内に `README.md` が配置される形の HTML ファイルが出力されます。

## 個人的な感想

HTML 周りに関してはできることが多く、JS があまり得意でない身としてはかなり使いやすい静的サイトジェネレーターだと感じました。
他にも JSON ファイルを使用したデータの分離や、データからのページ構築など、中~大規模の静的サイトを構築する上ではかなり強力な機能があります。CSS, JS 周りの環境を整えることができれば、個人的にはどんどん使っていきたいところです。少しずつ紹介していければと思います。