Html-webpack-plugin: Use html-webpack-plugin with an EJS file or stop webpack from evaluating variables

Created on 6 May 2017  ·  5Comments  ·  Source: jantimon/html-webpack-plugin

I want to use the HTMLWebpackPlugin to take a .EJS file and insert my bundled assets.

EJS is just a view template for Express that lets you do print variables into the HTML by doing <%= my_var %>.

This example has a EJS variable <%= API_URL %>, but webpack is interpreting it.

How can I stop webpack from substituting the variable?

Starting "template":

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Monitor</title>
        <script>
          window.config = {
            API_URL: "<%= API_URL %>"
          }
        </script>
      </head>
      <body>
        <div class="container"></div>
      </body>
    </html>

When you try to run webpack:

ERROR in Template execution failed: ReferenceError: FOOBAR is not defined

webpack.config.js

    var webpack = require('webpack');
    var path = require('path');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require('extract-text-webpack-plugin');

    module.exports = {
      entry: {
        bundle: './src/index.js'
      },
      output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].[chunkhash].js'
      },
      module: {
        rules: [
        {
          test: /\.js$/,
          use: 'babel-loader',
          exclude: /node_modules/
        },
        {
          // CSS is imported in app.js.
          test: /\.scss$/,
          use: ExtractTextPlugin.extract({
            fallbackLoader: 'style-loader',
            loader: ["css-loader", "sass-loader"]
          })
        }]
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env': {
            'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
            'API_URL': JSON.stringify(process.env.API_URL)
          }
        }),
        new HtmlWebpackPlugin({
          template: 'src/index.ejs',
          inject: true
        }),
        new ExtractTextPlugin("styles.css")
      ],
    };

Things I've tried:

Don't set any loader

There is a readme in this repo about how to use html-webpack-plugin with inline template vars. The first suggestion is to not specify any loader, stating that a fallback ejs loader kicks in.

This doesn't seem to be the case as running webpack is throwing the error about <%= FOOBAR %>, FOOBAR is undefined when it evaluates my index.ejs file.

Most helpful comment

@kimown
Here is mine which works for me:

        new HTML({
            template: '!!raw-loader!src/index.ejs',
            filename: 'index.ejs', //for me, output file is index.ejs only and not
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                conservativeCollapse: true
            }
        }),

All 5 comments

You can use the https://github.com/webpack-contrib/raw-loader which will ignore ejs templates

Hey @donpinkus
For your case,

Instead of API_URL: "<%= API_URL %>", use API_URL: "<%- API_URL %>" And it won't evaluate the variables.

Use filename: 'index.ejs' in html plugin config, otherwise, it renames file to.html`

@jantimon You're suggesting raw-loader! i don't think he needs to use raw-loader in case he is using ejs-loader because that's what the documentation you wrote suggests and works fine. With only issue that it outputs .html file instead of .ejs which can't be used directly with SSR.

{
                test: /\.ejs$/,
                loader: 'ejs-loader',
                query: {
                    interpolate : /\{\{(.+?)\}\}/g,
                    evaluate    : /\[\[(.+?)\]\]/g
                }
}

Otherwise, as you said, raw-loader can be used.

@aseem2625

With only issue that it outputs .html file instead of .ejs

Hi, I just made a test, you can use this configuration.

new HtmlWebpackPlugin({
      template: '!!raw-loader!' + path.join(__dirname, 'template/index.html.ejs'),
      filename: 'index.html.output.ejs'  // this line decide the extension of output file.
    })

After compiled, here is my out put:

.
├── bundle.js
└── index.html.output.ejs

@kimown
Here is mine which works for me:

        new HTML({
            template: '!!raw-loader!src/index.ejs',
            filename: 'index.ejs', //for me, output file is index.ejs only and not
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                conservativeCollapse: true
            }
        }),

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

var-bp picture var-bp  ·  3Comments

NeverwinterMoon picture NeverwinterMoon  ·  3Comments

yyx990803 picture yyx990803  ·  4Comments

hp8wvvvgnj6asjm7 picture hp8wvvvgnj6asjm7  ·  3Comments

MatthewKosloski picture MatthewKosloski  ·  3Comments