1

In another question, an accepted answer with 11 upvotes suggests using webpack's html-webpack-plugin to merge HTML+JS+CSS.

Not a single word on how though, so that's my question. I have a documentation file, in HTML. It includes two external CSS files and one javascript file (syntax highlighter). I would like to bundle it all into one HTML file for easy distribution.

I tried to use webpack without packing any JS with following webpack.config.js:

const HtmlWebpackPlugin = require("html-webpack-plugin");


module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Documentation',
            template: "index.html",
            filename: 'index_bundle.html'
        })
    ]
};

But that caused an error because webpack requires input and output script path:

Error: 'output.filename' is required, either in config file or as --output-filename

So how do I do this. Is webpack even the right choice?

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • When you say merge, do you expect javascript and css line of codes to be injected into the html file? If so, I think that's not what html-webpack-plugin does, it merely put a script / link tag pointing to the generated css/js. If this is all you need webpack to do, it's probably the wrong tool – Derek Nguyen Jan 18 '19 at 07:11
  • @DerekNguyen Yeah, well that's exactly what the linked question asked, and webpack is the accepted answer, so I kinda went from there. – Tomáš Zato Jan 19 '19 at 00:51

1 Answers1

0

What's tricky here is that webpack and HtmlWebpackPlugin each have their own entry-output pipeline. You don't care about webpack's entry point and output; you care about HtmlWebpackPlugin's, but in order for HtmlWebpackPlugin to run at all, you have to let webpack do its thing.

There's a clever trick that I stole from https://stackoverflow.com/a/43556756/152891 that you could do here -- tell webpack to output its bundle at index.html, and then tell HtmlWebpackPlugin to output to the same location. Webpack will run first, and then HtmlWebpackPlugin will overwrite its output. You still need to define an entry point for webpack, but this can be a blank index.js.

webpack.config.js:

const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'none',
  entry: './src/index.js', // Default value, can omit
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html', // Default value, can omit
      inject: false,
      minify: false
    })
  ],
  output: {
    filename: "index.html",
    path: path.resolve(__dirname, 'dist')
  }
};

You can either keep a blank ./src/index.js file in your repo, or you could define a little inline plugin in your webpack.config.js to create the file on run, and add it to your .gitignore.

  plugins: [
    {
      apply: (compiler) => {
        compiler.hooks.beforeRun.tap('NoOpPlugin', () => {
          fs.writeFileSync('./src/index.js');
        });
      }
    }
  ]
NReilingh
  • 1,730
  • 17
  • 32