Search code examples
javascriptwebpackejsbrowser-synchtml-webpack-plugin

Browser sync not re-rendering EJS partial files


I am using Browser Sync with Webpack and Express to develop a simple website using EJS templating. Everything is working fine other than the fact that browser sync does not seem to render the newly updated EJS partials when it reloads the browser.

However, it does actually notice that there is a change in the partial file and, when I save a change to it, reloads the browser window.

I have tried to use multiple paths which vary from **/*.ejs to directly setting the folders using an array, as demonstrated below:

        new BrowserSyncPlugin({
            files: ['src/views/pages/index.ejs', 'src/views/pages/partials/header.ejs'],
            proxy: `https://localhost:${process.env.PORT}`
        }),

I have a feeling this may be some kind of conflict with either Browser Sync, Html Webpack Plugin or EJS Webpack Loader. The relevant config lines are below:

        new BrowserSyncPlugin({
            files: ['src/views/pages/index.ejs', 'src/views/pages/partials/header.ejs'],
            proxy: `https://localhost:${process.env.PORT}`
        }),
        new HtmlWebpackPlugin({
            template: 'ejs-webpack-loader!src/views/pages/index.ejs',
            filename: 'index.html',
            domain: process.env.DOMAIN
        }),

And, to give some context, the header.ejs file is included as follows:

        <%- include partials/header.ejs %> 

I presume it is something to do with one of the loaders as browser sync is actually noticing the changes and reloading the page. The loader is simply not re-rendering includes. If I make a direct change to index.ejs it does actually re-render the change, though.

Thank you in advance.

EDIT:

My Express server config is as follows:

require('dotenv').config({path: './.env'});
const express = require('express');
const app = express();
const WebpackDevMiddleware = require('webpack-dev-middleware');
const https = require('https');
const fs = require('fs');
const config = require('../webpack.dev');
const helmet = require('helmet');
const webpack = require('webpack');
const compiler = webpack(config);

const {
    SSL_CERT,
    SSL_KEY,
    SSL_PW,
    PORT
} = process.env;
const httpsOptions = {
    key: fs.readFileSync(SSL_KEY),
    cert: fs.readFileSync(SSL_CERT),
    passphrase: SSL_PW
};
const secureServer = https.createServer(httpsOptions, app);
app.use(helmet());

app.use(WebpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
    reload: true
}));

const listener = secureServer.listen(PORT, () => console.log(`Connected on ${listener.address().port}`));

Another note, if I save the index.ejs it will render the changes made to the children.


Solution

  • The issue is with the ejs-webpack-loader plugin not handling re-rendering of included files.

    In order to get around this it is necessary to use the standard webpack require() method.

    SO, my index.ejs file now looks as follows:

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!--> <html class="no-js" lang="en-GB"> <!--<![endif]-->
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <%- include partials/head.ejs %> 
            <title>Making Stuffs | Coming Soon Boilerplate</title>
        </head>
        <body>
            <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
            <%- require ('ejs-webpack-loader!./partials/navbar.ejs')() %>
            <%- require ('ejs-webpack-loader!./partials/intro.ejs')() %> 
            <%- require ('ejs-webpack-loader!./partials/about.ejs')() %> 
            <%- require ('ejs-webpack-loader!./partials/portfolio.ejs')() %> 
            <%- require ('ejs-webpack-loader!./partials/contact.ejs')() %> 
            <%- require ('ejs-webpack-loader!./partials/blog.ejs')() %> 
        </body>
    </html>