[wp|3] Html Webpack Plugin

Apollo Tang
4 min readJan 27, 2017

--

____________________________________________

Download code here to follow this lesson.
Navigation: [ < Previous ][ Table of Content ][ Next > ]
_________________________________________________

In previous two lessons ([wp|1] [wp|2]) we have a script element in a static index.html file that load output of webpack bundle.js:

<script src="scripts/bundle.js"></script>

The following diagram summarizes how value of src attribute scripts/bundle.js relates to various output-path and output-chunk-name properties in webpack.config.js:

Because our index.html is statics, everytime we change the output-path (output.path or output.publicPath) or change the output-chankname (output.filename) we have to manually update the value for src attribute in index.html.

In addition to manually edit index.html, there are also numerous properties (output.path, output.publicPath, output.filename, and devServe.contentBase) need to be re-configured.

To simplify our work for rapid configurations change, we use html-webpack-plugin.

Let’s install html-webpack-plugin:

$ npm i -D --save-exact html-webpack-plugin 

We have a new folder structure:

We have renamed our index.html to index.template.html and place it in src/. The contents of index.template.html are:

This template will be used by html-webpack-plugin to generate index.html. Notice in the template, the script tag is commented out because it will be created dynamically.

We will also have a new webpack.config.js configuration setting:

Note the new attribute plugins, where we instantiates HtmlWebpackPlugin. During instantiation we also pass in options for name of template and favicon. Both of them has a path relative to src/ folder in our file system.

In this setup we have renamed value of output.path from 'public' to 'dist' (short for distribution). Webpack will now save its output to destination path/to/project/folder/dist/ .

We also configure output.publicPath to '/' which I will explain below, but for now let’s build this project:

$ npm run build

We can see in our terminal (above screenshot) that in addition to bundle.js two more items, favicon.ico and index.html were emitted and saved to dist/ folder:

Open up index.html in your editor to examine its content:

You can see the two injected html elements:

<link rel="shortcut icon" href="/favicon.ico"><script type="text/javascript" src="/bundle.js"></script>

Let’s now run our development:

$ npm run dev

webpack-dev-server now serving three items:

localhost:8080/bundle.js
localhost:8080/favicon.ico
localhost:8080/index.html

You can see the three items in browsers:

You may recall that previously in lesson [wp|2] bundle.js is served through URL path scripts/:

localhost:8080/scripts/bundle.js     //[wp|2]

where this URL path scripts/ was specified in webpack.config.js by:

output.publicPath:'scripts/'         //[wp|2]

In this lesson output.publicPath has a different value:

output.publicPath:'/'         //[wp|3]

html-webpack-plugin is using this value to set the path in index.html:

<script src="{output.publicPath}bundle.js"></script><link rel="shortcut icon" href="{output.publicPath}favicon.ico">

and server bundle.js via this path:

localhost:8080{output.publicPath}bundle.js

One property not present is devServer.contentBase. This is because we are now generates index.html from template; there is no need to tell webpack-dev-server where to look for index.html.

The following illustration summarizes what we have achieved in this lesson:

--

--