I’ve been following guides online and experimenting with integrating Webpack with Jekyll recently and I soon realised that there are certain aspects of the two tools that mean they need to be treated very specifically.

Build order matters

In an earlier more niave Jekyll/Webpack hybrid Jamstack implementation I’ve been building Webpack first and then piping the output to Jekyll as the second step. While this works to a point, it soon breaks down because some JS tools (Such as PurgeCSS) depend on your HTML in order to properly function. As a result the jekyll-webpack gem was born.

Compile HTML first, Assets Second

With this approach you only need one command jekyll build or jekyll serve and Webpacked assets are handled automatically as the last step in the build pipeline.

As such you can have a webpack config in your Jekyll project such as:-

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require("path");
const glob = require("glob-all");
const PurgecssPlugin = require("purgecss-webpack-plugin");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              sourceMap: true,
              plugins: [
                require('tailwindcss'),
                require('autoprefixer'),
              ],
            },
          }]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin(),
    new PurgecssPlugin({
      paths: glob.sync([
        path.join(__dirname, "**/*.html"),
        path.join(__dirname, "dist/**/*.js")
      ]),
      extractors: [
        {
          extractor: content => content.match(/[A-z0-9-:\/]+/g) || [],
          extensions: ["html", "js"]
        }
      ]
    })
  ]
};

Note that PurgeCSS is bundled in to Webpack now. There’s no need to have it as a seperate build step handled by a Jekyll plugin or such. Personally I prefer this style of asset configuration as it keeps it all in one place.

Installation and Usage instructions are available in the README