Even though webpack is often used for bundling single-page applications, it's possible to use it with multiple separate pages as well. The idea is similar to the way you generated many output files in the Targets chapter. That's achievable through MiniHtmlWebpackPlugin
and a bit of configuration.
If you want to map a directory tree as a website, see directory-tree-webpack-plugin.
When generating multiple pages with webpack, you have a couple of possibilities:
In practice, you have more dimensions. For example, you have to generate i18n variants for pages. These ideas grow on top of the basic approaches. Here we'll set up single configuration based on which to experiment further.
To generate multiple pages with webpack, we can leverage mini-html-webpack-plugin. html-webpack-plugin would work well for the purpose as well and using it would give you access to the plugins written for it. For the demonstration, using the former is enough.
A page should receive title, url, and chunks for deciding which scripts to include to the page. The idea can be modeled as a configuration part as below:
webpack.parts.js
const {
MiniHtmlWebpackPlugin,
} = require("mini-html-webpack-plugin");
exports.page = ({ title, url = "", chunks } = {}) => ({
plugins: [
new MiniHtmlWebpackPlugin({
publicPath: "/",
chunks,
filename: `${url && url + "/"}index.html`,
context: { title },
}),
],
});
To generate multiple pages using the new helper, set up a configuration file:
webpack.multi.js
const { merge } = require("webpack-merge");
const parts = require("./webpack.parts");
module.exports = merge(
{ mode: "production", entry: { app: "./src/multi.js" } },
parts.page({ title: "Demo" }),
parts.page({ title: "Another", url: "another" })
);
Implement a small module to render on the page:
src/multi.js
const element = document.createElement("div");
element.innerHTML = "hello multi";
document.body.appendChild(element);
And add a script to generate the pages:
package.json
{
"scripts": {
"build:multi": "wp --config webpack.multi.js"
}
}
After these steps, you have a minimal build with two pages: /
and /another
. To see it in the browser, run npx serve dist
to display the result. You should be able to navigate to both pages any other should not be available.
To control which entries are used on each page, use the chunks
parameter of parts.page
. If you set it to chunks: []
for one of the pages, you should see nothing on the page for example. While experimenting, match the name
given at parts.entry
. The parameter allows capturing chunks generated by Bundle Splitting and doing this would allow you to load a shared vendor
bundle for all pages.
To support development mode, see the Composing Configuration chapter on how to set it up. The development target requiresparts.devServer()
helper and a more complexmerge
operation based on the target type.
If you push the idea further by combining it with code splitting and smart routing, you'll end up with the idea of Progressive Web Applications (PWA). webpack-pwa example illustrates how to implement the approach using webpack either through an app shell or a page shell.
App shell is loaded initially, and it manages the whole application, including its routing. Page shells are more granular, and more are loaded as the application is used. The total size of the application is larger in this case. Conversely, you can load initial content faster.
Using Service Workers improves offline experience and especially Workbox and its associated workbox-webpack-plugin can be useful for setting up the approach with minimal effort.
Twitter and Tinder case studies illustrate how the PWA approach can improve platforms.
Webpack allows you to manage multiple page setups. The PWA approach allows the application to be loaded as it's used and webpack allows implementing it.
To recap:
You'll learn to implement Server-Side Rendering in the next chapter.
This book is available through Leanpub (digital), Amazon (paperback), and Kindle (digital). By purchasing the book you support the development of further content. A part of profit (~30%) goes to Tobias Koppers, the author of webpack.