1

*Edit: Example (hopefully) made more clear.


I'm sure there's something simple here I've missed, but I can't see it...

I'm using one HtmlWebPlugin instance with a template per page/entry point. When I use webpack-dev-server only the first instance actually respects what's in the template, the rest just use simple html and meta tags

Writing the files to disk, either by using WriteFilePlugin with dev-server, or by simply building the files without dev-server, uses the template correctly. I'm stumped.

Expected: about.html/index.html This is what I get using both write-file-webpack-plugin and by just running 'webpack --config webpack.config.js'. Index.html is identical.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About</title>
</head>
<body>
    <p>About</p>
</body>
</html>

Actual output from Webpack-dev-server: (view page source)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body>
        <script type="text/javascript" charset="utf-8" src="/about.js"></script>
    </body>

</html>

Config:

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
const path = require('path');

module.exports = {
    entry: {
        index: './src/js/index.js',
        about: './src/js/about.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.html$/,
                use: 'html-loader'
            }
        ]
    },
    devServer: {
        openPage: 'about'
    },
    plugins: [
        new WriteFilePlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'src/index.ejs',
            chunks: ['index']
        }),
        new HtmlWebpackPlugin({
            filename: 'about.html',
            template: 'src/about.ejs',
            chunks: ['about']
        }),
    ]
};

I can't see anything obviously wrong, but then I'm new to multiple pages and webpack

Thanks

**Edit: Given that the files written to disk are fine it feels like it might be a problem with where wds is serving files from or where I'm navigating to? localhost:8080 => html and script links are there. localhost:8080/index => script links but no html from the template. localhost:8080/about => script links but again no html from template.

i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from C:\Users\Nick\Javascript\Webpack\test
NickW
  • 1,207
  • 1
  • 12
  • 52
  • Have you tried adding the `plugins` section of your webpack.common.js file into your webpack.dev.js file? How will your webpack dev server know to use the HtmlWebpackPlugin in the way you've specified if its not in your webpack devserver config? Try adding it into the webpack.dev.js file. – Seth Lutske Jul 30 '20 at 15:22
  • Hey Seth, thanks I'll give it a try, but doesn't webpack-merge create a single config out of webpack.common.js and webpack.dev.js? – NickW Jul 30 '20 at 15:38
  • Unfortunately hasn't fixed the problem. Pretty sure webpack.common.js is being combined into one config file with webpack.dev.js, as adding ` devServer: {openPage: 'admin' },` to the former opens the correct page, and index.html does use the correct template. Thanks for the reply though – NickW Jul 30 '20 at 16:07

3 Answers3

2

Well, I might as well post my shame as the answer in case it helps anyone else in the future...

I was navigating to localhost:8080/about rather than localhost:8080/about.html.

The script was injected at /about, but the template wasn't. At /about.html both the script and template were used. I'm not sure why there's a difference there, but that was my problem!

NickW
  • 1,207
  • 1
  • 12
  • 52
  • 2
    See. When you go to `/about`, web server looks for `/about/index.html` by defaul, it **NOT AUTOMATICALLY** appends `html` file name into your path. That's it.. – ShinaBR2 Aug 02 '20 at 08:35
  • Isn't it weird that /about even exists then? If I navigate to /bout, for example, there isn't a route at all. But yeah, really nice to have found it! – NickW Aug 02 '20 at 08:45
  • With web server, whenever you don't specify the file name, it should be treat as a folder. – ShinaBR2 Aug 02 '20 at 09:07
1

I think you are missing a loader there check https://www.npmjs.com/package/ejs-webpack-loader

I found an example in the package page with HtmlWebpackPlugin, try it maybe it will help you

plugin: {
  new HtmlWebpackPlugin({
    template: '!!ejs-webpack-loader!src/index.ejs'
  })
}
Piyush Patel
  • 1,212
  • 15
  • 19
  • Nice idea but unfortunately it hasn't worked. Also, it works fine when writing the files to disk, so it feels like maybe it's an issue with dev-server and where or how it's serving files? I mentioned above that it works fine for `localhost:8080`, but not `localhost:8080/index` or `localhost:8080/about`, despite the javascript being injected for the latter 2 urls. Seems odd – NickW Aug 02 '20 at 06:25
0

As a reference here: https://github.com/jaketrent/html-webpack-template/issues/69#issuecomment-376872044.

In short answer, you need LOOP to all chunks to insert into your final html file.

Below is example code in your template file

<% for (var chunk in htmlWebpackPlugin.files.js) { %>
    <script src="<%= htmlWebpackPlugin.files.js[chunk]%>"></script>
<% } %>

Hope this help, please feel free if I got misunderstanding.

ShinaBR2
  • 2,519
  • 2
  • 14
  • 26
  • Hi Shina - The scripts/css and html are inserted correctly when I build the file though. It's when I use webpack-dev-server that they aren't. That seems like a slightly different problem to the one you linked? I'll definitely give it a try though as it might change dev-server's behaviour, thanks. – NickW Aug 02 '20 at 04:49
  • Same behaviour unfortunately. – NickW Aug 02 '20 at 04:55
  • Can you give me webpack version info? – ShinaBR2 Aug 02 '20 at 05:17
  • webpack 4.44.0. Have also rewritten/cut down the example to make it more clear – NickW Aug 02 '20 at 05:33
  • Also I've noticed that webpack-dev-server injects the html when at localhost:port, but not at localhost:port/index (or /about). Relevant js scripts are injected either way. Not sure if that gives an idea of what's happening? – NickW Aug 02 '20 at 05:40
  • Can you take a look at [this issue](https://stackoverflow.com/questions/45500038/html-webpack-plugin-is-only-injecting-js-in-root-route). I have done with these things long time ago and don't have any better idea now. – ShinaBR2 Aug 02 '20 at 05:54
  • Yeah that seems to be the reverse of my issue. The JS is injected fine, it's the html that isn't being rendered for me. His suggestion of it being an issue with the public path is something I've been looking at over the last 20 minutes, but haven't had any luck. See here: https://github.com/jantimon/html-webpack-plugin/issues/694 – NickW Aug 02 '20 at 06:06