SoFunction
Updated on 2025-04-07

webpack4 + react to build multi-page application example

After upgrading to 4, a practical webpack shelf has not been synchronized well. Next, use webpack4 to build a simple react multi-interface application. Don’t say nonsense, just use code

Create a project

$ mkdir demo && cd demo
$ npm init -y

webpack configuration

Install react + babel dependencies

(config -> webpack)

const entry = require("./");
const newEntry = {};
for (let name in entry) {
  newEntry[name] = entry[name][0]
}
let config = {
  entry: newEntry,
  resolve: {
    extensions: [".js", ".json", ".jsx", ".css", ".pcss"],
  }
};
 = config;


const webpack = require('webpack');//Introduce webpackconst opn = require('opn');//Open the browserconst merge = require('webpack-merge');//Webpack configuration file mergeconst path = require("path");
const baseWebpackConfig = require("./");//Basic configurationconst webpackFile = require("./");//Some path configurationconst eslintFormatter = require('react-dev-utils/eslintFormatter');

let config = merge(baseWebpackConfig, {
  /*Set the development environment*/
  mode: 'development',
  output: {
    path: (),
    filename: 'js/[name].js',
    chunkFilename: "js/[name].js",
    publicPath: ''
  },
  optimization: {
    runtimeChunk: {
      name: 'manifest'
    },
    // Package split    splitChunks: {
      cacheGroups: {
        common: {  // Public components of the project          chunks: "initial",
          name: "common",
          minChunks: 2,
          maxInitialRequests: 5,
          minSize: 0
        },
        vendor: {  // Third-party components          test: /node_modules/,
          chunks: "initial",
          name: "vendor",
          priority: 10,
          enforce: true
        }
      }
    }
  },
  plugins: [
    /*Set hot update*/
    new (),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: [
          'babel-loader',
          'cache-loader',
        ],
        include: [
          (__dirname, "../../app"),
          (__dirname, "../../entryBuild")
        ],
        exclude: [
          (__dirname, "../../node_modules")
        ],
      },
      {
        test: /\.(css|pcss)$/,
        loader: 'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,
        loader: 'file-loader?name=[name].[ext]&outputPath=' +  + '/'
      },
      {
        test: /\.(js|jsx)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              formatter: eslintFormatter,
              eslintPath: ('eslint'),
              // @remove-on-eject-begin
              baseConfig: {
                extends: [('eslint-config-react-app')],
              },
              //ignore: false,
              useEslintrc: false,
              // @remove-on-eject-end
            },
            loader: ('eslint-loader'),
          },
        ],
        include: [
          (__dirname, "../../app")
        ],
        exclude: [
          (__dirname, "../../node_modules")
        ],
      }
    ]
  },
  /*Set API forwarding*/
  devServer: {
    host: '0.0.0.0',
    port: 8080,
    hot: true,
    inline: true,
    contentBase: (),
    historyApiFallback: true,
    disableHostCheck: true,
    proxy: [
      {
        context: ['/api/**', '/u/**'],
         target: 'http://10.8.200.69:8080/',
         secure: false
       }
     ],
     /*Open the browser and open the website of this project*/
    after() {
      opn('http://localhost:' + );
    }
  }
});
 = config;


const path = require('path');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const baseWebpackConfig = require("./");
const webpackFile = require('./');
const entry = require("./");
const webpackCom = require("./");

let config = merge(baseWebpackConfig, {
  /*Set production environment*/
  mode: 'production',
  output: {
    path: (),
    filename: 'js/[name].[chunkhash:8].js',
    chunkFilename: "js/[name]-[id].[chunkhash:8].js",
  },
  optimization: {
    //Package list    runtimeChunk: {
      name: "manifest"
    },
    //Split the public package    splitChunks: {
      cacheGroups: {
        common: { //Project public components          chunks: "initial",
          name: "common",
          minChunks: 2,
          maxInitialRequests: 5,
          minSize: 0
        },
        vendor: {  //Third-party components          test: /node_modules/,
          chunks: "initial",
          name: "vendor",
          priority: 10,
          enforce: true
        }
      }
    }
  },
  plugins: [
    // extract css into its own file
    new ExtractTextPlugin('css/[name].[md5:contenthash:hex:8].css'),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      assetNameRegExp: /\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorOptions: {
        discardComments: {removeAll: true},
        // Avoid cssnano recalculating z-index        safe: true
      },
      canPrint: true
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: [
          'babel-loader',
        ],
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.(css|pcss)$/,
        use: ({
          fallback: "style-loader",
          use: "css-loader!postcss-loader"
        })
      },
      {
        test: /\.(png|jpg|gif|ttf|eot|woff|woff2|svg)$/,
        loader: 'url-loader?limit=8192&name=[name].[hash:8].[ext]&publicPath=' +  + '&outputPath=' +  + '/'
      },
      {
        test: /\.swf$/,
        loader: 'file?name=js/[name].[ext]'
      }
    ]
  }
});
let pages = entry;
for (let chunkName in pages) {
  let conf = {
    filename: chunkName + '.html',
    template: '',
    inject: true,
    title: (chunkName,pages[chunkName][1]),
    minify: {
      removeComments: true,
      collapseWhitespace: true,
      removeAttributeQuotes: true
    },
    chunks: ['manifest', 'vendor', 'common', chunkName],
    hash: false,
    chunksSortMode: 'dependency'
  };
  (new HtmlWebpackPlugin(conf));
}
/* Clear dist */
(new CleanWebpackPlugin([], {root: (__dirname, '../../'), verbose: true, dry: false}));


/* Copy static resources */
(function (data) {
  return (data)
});


 = config;

Build multi-interface

After the overall architecture is built

app -> component

$ mkdir demo && cd demo
$ touch 
  import React from 'react';
  class Index extends  {
    render() {
      return (
        <div className="demo">
          Write itdemo
        </div>
      );
    }
  }
    export default Index;

In config -> entry

 = [
  {
    name: 'index',
    path: 'index/',
    title: 'front page',
    keywords: 'front page',
    description: 'front page'
  },
  {
    name: 'demo',
    path: 'demo/',
    title: 'demo',
    keywords: 'demo',
    description: 'demo'
  },
  {
    name: 'demo1',
    path: 'demo1/',
    title: 'demo1',
    keywords: 'demo1',
    description: 'demo1'
  }
];

Then execute npm run create-dev directly and add a new and in devBuild and entryBuild



{
 "name": "webpack_es6",
 "version": "1.0.0",
 "description": "",
 "main": "",
 "scripts": {
  "dev": "webpack-dev-server --devtool eval --progress --colors --profile --config config/webpack/",
  "entry": "node config/entry/",
  "devBuildHtml": "node config/webpack/",
  "create-dev": "npm run entry && npm run devBuildHtml",
  "build": "BABEL_ENV=production && webpack --progress --colors --config config/webpack/",
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": {
  "react": "^16.3.0",
  "react-dom": "^16.3.0"
 },
 "devDependencies": {
  "babel-cli": "^6.26.0",
  "babel-eslint": "^8.2.2",
  "babel-loader": "^7.1.4",
  "babel-preset-env": "^1.6.1",
  "babel-preset-react": "^6.24.1",
  "babel-preset-react-hmre": "^1.1.1",
  "cache-loader": "^1.2.2",
  "clean-webpack-plugin": "^0.1.19",
  "copy-webpack-plugin": "^4.5.1",
  "css-loader": "^0.28.11",
  "eslint": "^4.19.1",
  "eslint-config-react-app": "^2.1.0",
  "eslint-loader": "^2.0.0",
  "eslint-plugin-flowtype": "^2.46.1",
  "eslint-plugin-import": "^2.10.0",
  "eslint-plugin-jsx-a11y": "^5.1.1",
  "eslint-plugin-react": "^7.7.0",
  "extract-text-webpack-plugin": "^4.0.0-beta.0",
  "file": "^0.2.2",
  "file-loader": "^1.1.11",
  "html-webpack-plugin": "^3.1.0",
  "optimize-css-assets-webpack-plugin": "^4.0.0",
  "postcss-cssnext": "^3.1.0",
  "postcss-loader": "^2.1.3",
  "precss": "^3.1.2",
  "react-dev-utils": "^5.0.0",
  "style-loader": "^0.20.3",
  "url-loader": "^1.0.1",
  "webpack": "^4.4.1",
  "webpack-cli": "^2.0.13",
  "webpack-dev-server": "^3.1.1",
  "webpack-merge": "^4.1.2"
 },
 "eslintConfig": {
  "extends": "react-app",
  "rules": {
   "import/no-webpack-loader-syntax": 0,
   "no-script-url": 0,
   "jsx-a11y/href-no-hash": 2
  }
 }
}

Tips for development environment

Adding cache-loader in the development environment can improve the compilation speed in the development environment

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.