Pass variables from html-webpack-plugin to pug template

Viewed 4175

Is it possible to pass a variable to the .pug template loaded by the 'pug-html-loader' which I defined in the 'html-webpack-plugin' before?

webpack.config.babel.js

...

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


...

 plugins: [

        new HtmlWebpackPlugin({
            chunks: ['index'],
            filename: 'index.html',
            template: './src/templates/layout.pug',
            title: 'Welcome',
            file: 'index'
        }),

        new HtmlWebpackPlugin({
            chunks: ['index', 'contact'],
            filename: 'contact.html',
            template: './src/templates/layout.pug',
            title: 'Contact us',
            file: 'contact'
        }),

]

In a layout.html I have defined as follows:

<!doctype html>
<html class="no-js" lang="en">
<head>
    <meta charset="utf-8">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>

<main>
    ${ require('html-loader!../partials/' + htmlWebpackPlugin.options.file + '.html' ) }
</main>

</body>
</html>

How can I use it to pass all variables - defined in the Webpack plugin for the usage in my PugTemplates and files? The application is supposed to be a simple process for creating simple webpages, which consists of several static pages.

5 Answers

For those that are having trouble with this answer. The solution is to create a templateGenerator

Example:

new HTMLWebpackPlugin({
   inject: true,
   templateParameters: paramGenerator(globals), // <--- Here
   template: '/mytemplate.pug',
}),
import { environment } from '../environment';

export function paramGenerator(globals: () => {[key: string]: any}) {
  return (compilation, assets, assetTags, options) => {
    return {
      compilation: compilation,
      webpackConfig: compilation.options,
      htmlWebpackPlugin: {
        tags: assetTags,
        files: assets,
        options: options
      },
      environment,
      ...globals(),
    };
  }
}

Where globals is a function that returns a simple object that is attached to your global pug scope.

I have tried to use templateParameters at HtmlWebpackPlugin, it seems not working.

But find a sample here https://github.com/jantimon/html-webpack-plugin/tree/main/examples/template-parameters, and this is a sample to pass variables into ejs template files

Then I got the answer at pug-html-loader, it can pass data into pug files, just use the 'data' property at options, like below, I add an 'IMG_PREFIX' in it.

module.exports = {
  rules: [
    loaders: [{
      include: /\.pug/,
      loader: ['pug-html-loader'],
      options: {
        data: {
          IMG_PREFIX: '/'
        }
      }
    }]
  ]
};

then you can receive the variable at pug file and use it

- var imgPrefix = IMG_PREFIX

div.avatar-block
    img.avatar(src=imgPrefix+'xxx.jpg')

your code should work.

Is there any particular reason why you are using html-loader ?

Although nothing stops you from making use of multiple templates in your app or even chain load them if they convert nicely; we usually make use of one templating engine. Now, I haven't taken a look at the html-loader source code, but from the comment posted at the link provided below, html-loader does not support template parameters. It does not make use of them, pass it down or up to other loaders in the same chain.

In short, Template parameters do not work in html-loader and that may be the reason why you're having this issue.

Try removing the html-loader and see if that fixes it.

https://github.com/jantimon/html-webpack-plugin/issues/1400

Related