問題設定

Jekyllは静的サイトジェネレータであるが、JavaScriptによって動的な部分を作ることは可能である。 ここでは、webpackを使ってJavaScriptのコードを管理しつつ、JekyllでJavaScriptを利用する方法を紹介する。

インストール

Jekyllサイトに webpack をインストールする。 あらかじめ npmプロジェクトとして設定されているものとすると、以下のコマンドで必要なモジュールをインストールできる。babelは、ES6(ES2015)を使用するためモジュールである。

$ npm install --save-dev webpack webpack-cli
$ npm install --save-dev @babel/core @babel/preset-env babel-loader @babel/polyfill

webpackの設定

webpack.config.jsを以下に内容とする。 これで assets/jsにある main.js が webpackでトランスコンパイルされて、assets/js/main-bundle.js として出力される。

const path = require("path");
const webpack = require("webpack");


module.exports = {
  mode: "production",
  watch: true,
  entry: path.join(__dirname, "webpack", "main.js"),
  output: {
    path: path.resolve(__dirname, "assets/js"),
    filename: "[name]-bundle.js",
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: [
          path.resolve(__dirname, "node_modules"),
          path.resolve(__dirname, "bower_components"),
        ],
        use: [
          {
            // Babel を利用する
            loader: "babel-loader",
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES2019 を ES5 に変換
                "@babel/preset-env"
              ]
            }
          }
        ]
      },
    ],
  },
  resolve: {
    extensions: [".json", ".js", ".jsx"],
  },
};

package.jsonのscriptsの項目に以下を追記する。

{
  "scripts": {
    "start": "./node_modules/.bin/webpack --watch | bundle exec jekyll serve --incremental",
    "drafts": "./node_modules/.bin/webpack --watch | bundle exec jekyll serve --drafts --incremental",
    "build": "./node_modules/.bin/webpack | bundle exec jekyll build"
  },
}

JavaScriptをページごとに読みこめるように設定する

default.htmlのbodyタグのなかに以下を追記する。


  <html lang="{{ site.locale | slice: 0,2 | default: "en" }}" class="no-js">
    <body ...>

      ここから
      {% if page.js_bundle %}
        <script type="text/javascript" src="/assets/js/{{ page.js_bundle }}.js" async></script>
      {% endif %}
      ここまで
    </body>
  </html>

実例

実例として現在の日付をページに表示してみる。

まずは、webpack/main.js に以下の内容を記述する。

"use strict";
import '@babel/polyfill';

$(() => {
  return setInterval(_ => {
    $('#date').text(new Date())
  })
} , 1000);

次に、jekyllのページを以下の内容で作成する。 このとき js_bundle: main-bundle とすることで、main.jsが読みこまれる。

---
layout: single
title:  "jekyllでwebpackを使う"
js_bundle: main-bundle
---

<div id="date">
</div>

参考資料

  • https://michaelmovsesov.com/articles/jekyll-es6-workflow
  • https://qiita.com/fukafuka_dev/items/32415608354028684c05