Search code examples
variableswebpackpughtml-webpack-plugin

HtmlWebpackPlugin doesn't pass pug variables to included pug file


I have a basic understanding of how webpack and pug can work together, using HtmlWebpackPlugin to generate a page with the bundled assets using the pug template.

I've created a very simple test project with two pug files: head.pug contains the stuff that goes in <head>, and index.pug is the rest. I created some variables in index.pug which I expect to use in head.pug by using include head.pug. Here is what they look like:

// head.pug //
title #{title}

if isProduction
    base(href='myurl.com/welcome/')

// index.pug //
- var isProduction = true
- var title = 'Testing'

doctype html
html
    head
        include head.pug
    body
        p My Site

If I use the pug-cli to compile index.pug, it creates the following index.html file:

<!DOCTYPE html>
<html>
    <head>
        <title>Testing</title>
        <base href="myurl.com/welcome/">
    </head>
    <body>
        <p>My Site</p>
    </body>
</html>

Looks good. Now, if I use webpack to build my assets and generate index.html, it looks like this:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
    <body>
        <p>My Site</p>
        <script src="/bundle6028aa4f7993fc1329ca.js"></script>
    </body>
</html>

As you can see, the title wasn't defined, and isProduction is false, so <base> isn't inserted. What's going wrong? Here is my webpack config file:

const webpack = require('webpack');
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle[contenthash].js'
  },
  module: {
    rules: [
      { test: /\.pug$/, loader: "pug-loader" },
    ]
  },
  plugins: [
    new CleanWebpackPlugin(), 
    new HtmlWebpackPlugin({
      template: '!!pug-loader!src/pug/index.pug',
      filename: path.join(__dirname, 'dist/index.html')
    })
  ]
};

Solution

  • Use the Webpack rule for pug files with these loaders:

    ...
    {
        test: /\.pug$/,
        use: [
            {
                loader: 'html-loader'
            },
            {
                loader: 'pug-html-loader'
            }
        ],
    },
    ...
    

    And maybe you can rid of !!pug-loader! for the plugins template property:

    ...
    new HtmlWebpackPlugin({
        template: './src/pug/index.pug',
        filename: path.join(__dirname, 'dist/index.html')
    })
    ...
    

    Probably you have to install the loaders via npm:

    npm i html-loader pug-html-loader