This is the 28th day of my participation in the August Challenge

Previously we practiced the use of global variables exposed in WebPack and webPack built-in plug-ins; Today we will practice configuring multi-page applications and sourceMap;

A, sourceMap

In order to improve the performance of the code, we have enabled webPack to compress the obliqued code, but if the code runs incorrectly, compressing the obliqued code is very bad for debugging. To solve this problem, we need a mechanism called sourceMap. SourceMap is a browser feature that can virtually restore compressed and obtruded code to source code based on the sourceMap configuration. Webpack has the configuration built in, and we turned sourceMap on by configuring the devtool option at packaging time; SourceMap has the following optional values:

  • source-map, generate source-map and full code map, output.map file separately
  • eval-source-mapGenerates a row and column map, but does not generate a separate source-map file
  • cheap-module-source-mapThe resulting source-map, without rows and columns, produces a separate.map file
  • cheap-module-eval-source-mapGenerates source-map without rows and columns, and does not output a.map file

It is worth mentioning that the above order is in descending order of detail, with the lower the level of detail. Eval-source-map is usually used in the eval-source-map. But it depends. If you need source-map files in your project, such as using an error monitoring system like Sentry, then you need to configure how to produce files.

1.1 Modifying the Configuration File Enable sourcemap

const path = require('path');

module.exports = {
  entry: './src/index.js',
  // mode: 'development',
  mode: 'production',
+ devtool: "eval-source-map", // source-mapoutput: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, devServer: { }, module: { rules: []}, plugins: [], // Configure externals externals: {vue: 'Vue' // import Vue from 'Vue' will look for window.vue}}Copy the code

1.2 Effect as shown in figure

Webpack configures multi-page applications

In our previous examples, we used the popular single-page application configuration, but there are many cases where we encounter multi-page applications. Webpack also supports multi-page application processing; Multiple pages involve several issues:

  • Multi-entry, js file entry is no longer a JS file;
  • Multi-exit, multiple pages rely on different JS files, so the corresponding need to output multiple JS files
  • Common module separation issues, where multiple pages in a project may rely on the same modules that do not need to be packaged multiple times

2.1. The problem of multiple entrances and multiple exits

To solve multiple entry, we need to configure an object in the Entry of webpack; To solve the problem of multiple exports, the output configuration item needs to be modified. Filename of output is a fixed bundle.js. However, the name of the multi-page application should be determined by its entry file, so it cannot be written as a fixed string, with the multi-page application [name] representing the file name, [hash:5] generating the file name followed by a 5-bit hash stamp;

Finally, each page also needs to import a specific JS file, which should not be confused. For example, the index.html section introduces index.js, and the other. HTML section introduces other.js. Therefore, we need to modify the configuration of HTMLWebpackPlugin. At this time, there is no longer one instance of HTMLWebpackPlugin, but one instance per page, and add the chunks configuration field in the configuration of each instance. Identify which code blocks are required for the current HTML file. After configuring these contents, after webpack is packaged, js code blocks originally belonging to the page will be automatically inserted into the page, so that we initially realize the configuration of a multi-page application;

  • Modify thewebpackThe configuration file

module.exports = {
  // entry: './src/index.js',
  // mode: 'development',
  mode: 'production',
  devtool: 'eval-source-map',
  entry: {
    home: './src/index.js',
    other: './src/other.js',
    x: './src/x.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
+ filename: '[name].[hash].js'}, devServer: {// devServer configuration}, module: {rules: []}, plugins: [// Set one instance of htML-webpack-plugin for each HTML file, and the chunks property is the js file that needs to be introduced in the current page. If there are more than one, set multiple js files in the array
+ new HTMLWebpackPlugin({
+ template: './src/index.html',
+ filename: "index.html",
+ chunks: ['home']
+}).
+ new HTMLWebpackPlugin({
+ template: './src/other.html',
+ filename: "other.html",
+ chunks: ['other']
+}).New CleanWebpackPlugin(), // Copy the contents of the file: // Print the necessary information in the packaged code. New webpack.BannerPlugin(' Make a wish, make a wish, make a wish; Minimizer: {minimizer: []}, // configure externals}Copy the code

2.2 Remove public modules

After the above configuration, a multi-page application can be packaged; If both index.js and other.js depend on the x.js module, we will find that the x module is packaged with both index.js and other.js. If the module is dependent on more modules, it will be packaged more times, which increases the size of the code. To solve this problem, we need to configure the extract common module;

To extract common modules, you need to change the optimization.splitchunks option in webpack.config.js to split code. After Webpack4.x, this function is used instead of CommonChunksPlugin.

  • The configuration is as follows:

  • CacheGroups: Object a cache group in which each key corresponds to a chunk output to the file output directory. In short, a key is a common module.

    • Common: Object, which defines a public module called common
      • Chunks: ‘initial’, indicating which modules will be optimized
      • MinSize: 0. If the packaged code exceeds this limit, the code block will be extracted and become a public module. If it does not exceed this limit, it will still be packaged into the code and will not become a separate module
      • MinChunks: 2, the minimum number of times a code block will be extracted into a common module that needs to be referenced
    • Vendors: Object, which defines a second module called Vendors to extract third-party code
      • Priority: 1, priority, priority to extract third-party code
      • test: /node_modules/,
      • chunks: ‘initial’,
      • minSize: 0,
      • minChunks: 2
  • Modifying a Configuration File

module.exports = { mode: 'development', devtool: 'eval-source-map', entry: { home: './src/index.js', other: './src/other.js', x: './src/x.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash].js' // With multi-page application [name] indicates file name, [hash:5] generates file name followed by 5-bit hash stamp}, devServer: {// Configuration of development server}, module: Optimization: {minimizer: [], minimizer: [],+ splitChunks: {
+ cacheGroups: {
+ common: {
+ chunks: 'initial',
+ minSize: 0,
+ minChunks: 2,
+},
+ vendors: {
+ priority: 1,
+ test: /node_modules/,
+ chunks: 'initial',
+ minSize: 0,
+ minChunks: 2
+}
+}
+}}, // externals externals: {vue: 'vue' // import vue from 'vue', look for window.vue}}Copy the code

After the above configuration, we execute the package command again, check the package output file again, we find that there will be an extra file, file name has ~ character, this file is extracted from the public module, including this ~ can be configured.