独学者Fossa

独学していることなど

Vite + Nunjucks

Vituumを使わず、Viteを使って、NunjucksHTMLを生成する方法です。

2023-06-28 追記
Vituumが1.0.0となり、仕様が変更されました。
@vituum/vite-plugin-nunjucksの1.0.0では、下記の通りには動作しません。

使用環境

Name Version
Vite 4.0.3
@vituum/vite-plugin-nunjucks 0.1.5

フォルダ構造

├── copy      ← ViteのDefaultは、public
├── package.json
├── public    ← ViteのDefaultは、dist
├── src
│   ├── index.html
│   ├── pages
│   │   ├── a
│   │   │   └── index.html
│   │   └── b.html
│   ├── scripts
│   │   └── main.js
│   ├── styles
│   │   └── main.scss
│   └── templates
│       └── layouts
│           └── master.njk
└── vite.config.js

src/index.html

{% extends 'templates/layouts/master.njk' %}

{% block css %}
<link rel="stylesheet" href="/styles/main.scss">
{% endblock -%}

{% block js %}
<script type="module" src="/scripts/main.js"></script>
{% endblock -%}

{% block contents -%}
<h1>コンテンツ</h1>
{%- endblock %}

templates/layouts/master.njk

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>{% block title %}{% endblock %}</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  {% block css -%}{% endblock -%}
  {% block js -%}{% endblock -%}
</head>
<body>
  {% block contents %}{% endblock %}
</body>
</html>

vite.config.js

import { defineConfig } from 'vite';
import fastGlob from 'fast-glob';
import nunjucks from '@vituum/vite-plugin-nunjucks';
import path from 'node:path';

// https://vitejs.dev/config/
export default defineConfig({
  root: path.join(__dirname, 'src'),
  publicDir: path.join(__dirname, 'copy'),
  plugins: [
    nunjucks({
      filetypes: {
        html: /.(html|njk|njk.html)$/,
      },
    }),
  ],
  build: {
    emptyOutDir: true,
    outDir: path.join(__dirname, 'public'),
    rollupOptions: {
      input: fastGlob.sync(['src/*.html', 'src/pages/**/*.html'], { dot: false }),
    },
  },
});

ポイントは、filetypeshtmlhtmlを記載することです。

src/index.htmlの中身はNunjucksのテンプレートなので、src/index.njksrc/index.njk.htmlにしたいのですが、うまく動きません。

ファイル名 動作
src/index.njk index.htmlが存在しないので、エラー
src/index.njk.html 展開するが、public/index.njk.htmlが生成

templates/layoutstemplates/partialsなど、extendsincludeで読まれる方は、njkファイルにするのも、ポイントかな?

補足説明

上記だと、src(public)フォルダ以下か、src(public)/pagesフォルダ以下にしか、HTMLファイルが配置できません。

試してないので、動作は確認していませんが、下記のようにすれば、自由度が高くなるかも?

    rollupOptions: {
      input: fastGlob.sync(['src/**/*.html'], { dot: false }),
    },