Implementation steps for building multi-page programs using Webpack

Implementation steps for building multi-page programs using Webpack

It is very common to use webpack to build single-page programs, but in actual development we may also need to develop multi-page programs, so I studied how to use webpack to build multi-page programs.

principle

Treat the folder where each page is located as a separate single-page program directory, and configure multiple entries and html-webpack-plugin to achieve multi-page packaging.

The following is the directory structure of this project

.
├─ src
│ └─ pages
│ ├─ about
│ │ ├─ index.css
│ │ ├─ index.html
│ │ └─ index.js
│ └─ index
│ ├─ index.css
│ ├─ index.html
│ └─ index.js
└─ webpack.config.js

Single page packaging basic configuration

First, let's take a look at the basic configuration of webpack for single-page applications.

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

module.exports = {
 entry: './src/index.js',
 plugins: [
  new HtmlWebpackPlugin({
   template: './src/index.html',
   filename: 'index.html',
  }),
 ],
 output: {
  path: path.resolve(__dirname, './dist'),
  filename: 'bundle.js',
 },
};

To change it to a multi-page application, you need to change its single entry and single HTML template to multiple entry and multiple HTML templates.

Basic configuration of multi-page packaging

Renovation entrance

Traditional multi-entry writing can be written in the form of key-value pairs

module.exports = {
 entry: {
  index: './src/pages/index/index.js',
  about: './src/pages/about/index.js',
 },
 ...
}

If written in this way, each additional page needs to manually add an entry, which is troublesome. Therefore, we can define a function to generate an entry based on the directory to simplify our operation.

const glob = require('glob');

function getEntry() {
 const entry = {};
 glob.sync('./src/pages/**/index.js').forEach((file) => {
  const name = file.match(/\/pages\/(.+)\/index.js/)[1];
  entry[name] = file;
 });
 return entry;
}

module.exports = {
 entry: getEntry(),
 ...
}

Transformation output

In the output configuration, it is no longer appropriate to hard-code the output file name, so we need to change the name to match the source file name

module.exports = {
 ...
 output: {
  path: path.resolve(__dirname, './dist'),
  filename: 'js/[name].[contenthash].js',
 },
 ...
}

Configure multiple html-webpack-plugins

Same as the entry, different html templates can be written directly into the plugin configuration. Here we need to configure different chunks for each plugin to prevent js from being injected into the wrong html

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

module.exports = {
 ...
 plugins: [
  new HtmlWebpackPlugin({
   template: './src/pages/index/index.html',
   chunks: ['index'],
   filename: 'index.html',
  }),
  new HtmlWebpackPlugin({
   template: './src/pages/about/index.html',
   chunks: ['about'],
   filename: 'about.html',
  }),
 ],
 ...
};

This approach has the same problem as the entry, so we define another function to generate this configuration

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

function getHtmlTemplate() {
 return glob
  .sync('./src/pages/**/index.html')
  .map((file) => {
   return { name: file.match(/\/pages\/(.+)\/index.html/)[1], path: file };
  })
  .map(
   (template) =>
    new HtmlWebpackPlugin({
     template: template.path,
     chunks: [template.name.toString()],
     filename: `${template.name}.html`,
    })
  );
}

 
module.exports = {
 ...
 plugins: [...getHtmlTemplate()],
 ...
};

Such a simple multi-page project has been configured. We can also add hot update, code splitting and other functions on this basis. If you are interested, you can try it yourself.

Complete Configuration

Project address: xmy6364/webpack-multipage

// webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const glob = require('glob');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

//Multi-page entry function getEntry() {
 const entry = {};
 glob.sync('./src/pages/**/index.js').forEach((file) => {
  const name = file.match(/\/pages\/(.+)\/index.js/)[1];
  entry[name] = file;
 });
 return entry;
}

//Multi-page template function getHtmlTemplate() {
 return glob
  .sync('./src/pages/**/index.html')
  .map((file) => {
   return { name: file.match(/\/pages\/(.+)\/index.html/)[1], path: file };
  })
  .map(
   (template) =>
    new HtmlWebpackPlugin({
     template: template.path,
     chunks: [template.name.toString()],
     filename: `${template.name}.html`,
    })
  );
}

const config = {
 mode: 'production',
 entry: getEntry(),
 output: {
  path: path.resolve(__dirname, './dist'),
  filename: 'js/[name].[contenthash].js',
 },
 module: {
  rules:
   {
    test: /\.css$/,
    use: ['style-loader', 'css-loader'],
   },
  ],
 },
 plugins: [new CleanWebpackPlugin(), ...getHtmlTemplate()],
 devServer: {
  contentBase: path.join(__dirname, 'dist'),
  compress: true,
  port: 3000,
  hot: true,
  open: true,
 },
};

module.exports = config;

This concludes this article on the implementation steps of using Webpack to build a multi-page program. For more relevant content about building multiple pages with Webpack, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Electron-vue uses webpack to package multiple pages of entry files
  • Implementation of webpack code fragmentation
  • How to debug loader plugin in webpack project
  • 80 lines of code to write a Webpack plugin and publish it to npm
  • 50 lines of code to implement Webpack component usage statistics
  • webpack -v error solution

<<:  How to configure Nginx to support ipv6 under Linux system

>>:  Linux C log output code template sample code

Recommend

20 JS abbreviation skills to improve work efficiency

Table of contents When declaring multiple variabl...

A brief discussion on what situations in MySQL will cause index failure

Here are some tips from training institutions and...

Simple Mysql backup BAT script sharing under Windows

Preface This article introduces a simple BAT scri...

Use the more, less, and cat commands in Linux to view file contents

In Linux, the commands cat, more, and less can al...

Detailed analysis of the parameter file my.cnf of MySQL in Ubuntu

Preface Based on my understanding of MySQL, I thi...

Detailed explanation of Vue data proxy

Table of contents 1. What I am going to talk abou...

Markup Language - Title

Click here to return to the 123WORDPRESS.COM HTML ...

A brief discussion on how Tomcat breaks the parent delegation mechanism

Table of contents JVM Class Loader Tomcat class l...

Detailed explanation of simple snow effect example using JS

Table of contents Preface Main implementation cod...

Web designer's growth experience

<br />First of all, I have to state that I a...

Common scenarios and avoidance methods for index failure in MySQL

Preface I have read many similar articles before,...

Detailed explanation of fetch network request encapsulation example

export default ({ url, method = 'GET', da...

Method and introduction of table index definition in MySQL

Overview An index is a table of correspondence be...