Several ways to manually implement HMR in webpack

Several ways to manually implement HMR in webpack

1. Introduction

As we all know, using hot module replacement (HMR) in webpack can update the changed modules when the application is running, without the developer having to re- npm run dev and refresh the page, and the effect can be displayed in time, which undoubtedly greatly improves the lives of front-end students.
Of course, there are many scaffolds at present, such as vue-cli, create-react-app, etc. Through these scaffolds, we can easily build projects, and these scaffolds automatically configure the hot update function for us. From now on, we no longer need webpack configuration engineers [escape]
But in some cases, we still need to manually configure hot updates. This blog mainly shares several methods for manually configuring hot updates.

2. GitHub

GitHub

3. Basic Configuration

Because we use the Vue framework for development (of course other frameworks can also be used), some configuration is required first.

Project Directory

這里寫圖片描述

The build directory contains the webpack configuration file
Below src is the project code

package.json

Needless to say, the first step is to install various dependencies. The basic dependencies are as follows

"devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "cross-env": "^5.1.6",
    "css-loader": "^0.28.11",
    "html-webpack-plugin": "^3.2.0",
    "moment": "^2.22.2",
    "vue-loader": "^15.2.4",
    "vue-template-compiler": "^2.5.16",
    "webpack": "^4.11.1",
    "webpack-cli": "^3.0.3",
    "webpack-merge": "^4.1.2"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0",
    "vue": "^2.5.16"
  }

webpack.config.js

Create a new webpack.config.js in the build directory for backup. This file is mainly used as the basic configuration file for webpack. Generally, we distinguish between dev (development) and build (production), but some configurations of the two situations are the same, so establishing a public configuration file can reduce the amount of code. The code in webpack.conf.js is as follows

const path = require('path');
const webpack = require('webpack');
const package = require('./../package.json');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const moment = require('moment');
// Set the version number const buildVersion = moment().format('YYYY-MM-DD_HH_mm_ss');

module.exports = {
    entry: path.join(__dirname, '../src/pages/main.js'),
    output: {
        path: path.resolve(__dirname, '../dist'),
        publicPath: '/',
        filename: package.name + '.js'
    },
    module: {
        rules:[
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {}
            },
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            version: buildVersion,
            filename: 'index.html',
            template: path.join(__dirname, '../src/pages/index.html'),
            inject: 'body'
        })
    ],
    externals: {
        'babel-polyfill': 'window'
    },
    devtool: 'source-map'
}

The code is simple and not difficult to understand

main.js

This file is mainly used to create a vue instance

import 'babel-polyfill'
import Vue from 'vue'

import App from '../container/main.vue'

new Vue({
    el: '#app',
    render: h => h(App)
})

index.html

Playing the role of template

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>dev-server HRM</title>
    <meta name="robots" content="all" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover"
    />
    <!-- Show toolbar and menu bar -->
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <!-- Toolbar and menu bar styles -->
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <!-- Optimized for handheld devices, mainly for some old browsers that do not recognize viewport, such as BlackBerry-->
    <meta name="HandheldFriendly" content="true" />
    <!-- Ignore numbers in the page and identify them as phone numbers-->
    <meta name="format-detection" content="telephone=no" />
</head>
<body>
    <div id="app"></div>
</body>
</html>

main.vue

Mainly used to test whether hot loading is successful

4.webpack-dev-server

Webpack can build a local server by using webpack-dev-server, which is equivalent to a small express, and we can use it to implement hot loading

package.json

After installing webpack-dev-server we need to configure the script field in package.json

"scripts": {
  "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/dev.config.js",
   "build": "cross-env NODE_ENV=production webpack-dev-server --config build/build.config.js",
  "test": "echo \"Error: no test specified\" && exit 1"
}

It should be noted that we can set and use environment variables across platforms through cross-env. We use it to set whether it is development or production

dev.config.js

Create a new dev.config.js in the build directory as the webpack configuration file for dev

const webpack = require('webpack')
const config = require('./webpack.config.js')

// Variables that need to be configured starting with webpack4 config.mode = "development";

config.devServer = {
    historyApiFallback:true,
    // The hot parameter controls whether the update refreshes the entire page or a partial refresh hot: true,
    // inline is a hot update mode, the other is iframe
    inline: true,
    port: 80
}

// Be sure to add HotModuleReplacementPlugin
config.plugins.push(
    new webpack.HotModuleReplacementPlugin()
)

// Need to export module.exports = config;

Finish

Run npm run dev and modify main.vue. No need to refresh the browser, webapck will automatically package and update it for us.
In fact, you can directly determine whether to start hot reload in the console network

這里寫圖片描述

webpack-dev-server uses websocket to send update information to the browser

5.webpack-dev-middleware + webpack-hot-middleware

In addition to using webpack-dev-server, we can also use webpack-dev-middleware + webpack-hot-middleware to achieve hot reload, but neither of these two modules has server functions, we also need to install express

package.json

Similarly, after all dependencies are installed, you need to configure the script field in package.json

"scripts": {
  "dev": "cross-env NODE_ENV=development node ./build/dev.config.js",
  "build": "cross-env NODE_ENV=production node ./build/build.config.js",
  "test": "echo \"Error: no test specified\" && exit 1"
},

dev.config.js

With this solution, dev.config.js needs to write more code

const app = require('express')();
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpackHotMiddleware = require("webpack-hot-middleware");
const path = require("path");
let config = require("./webpack.config")

config.mode = "development";

// Very important config.entry = [config.entry,'webpack-hot-middleware/client'];

config.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    // When HMR is enabled, this plugin will display the relative path of the module. It is recommended for development environment new webpack.NamedModulesPlugin()
)

const compiler = webpack(config);

// Using dev-middleware and hot-middleware

const devMiddleware = webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
    quiet: true
})

const hotMiddleware = webpackHotMiddleware(compiler, {
    log: false,
    heartbeat: 2000
})

app.use(devMiddleware);
app.use(hotMiddleware);
app.listen(80);

Unlike webpack-dev-server, since neither of the two modules used here have server functions, we can only use express to start the service

Finish

Run npm run dev and modify main.vue. No need to refresh the browser, webapck will automatically package and update it for us.
You can also directly determine whether to start hot reload in the console network

這里寫圖片描述

In this case, webpack uses eventSource to communicate with the browser. Unlike websocket two-way communication, eventsource can only communicate from the server to the client.

This concludes this article about several ways to manually implement HMR with webpack. For more related webpack HMR content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Electron-vue uses webpack to package multiple pages of entry files
  • How webpack implements static resource caching
  • Summary of webpack's mobile adaptation solution
  • How to use vue-cli to create a project and package it with webpack
  • Summary of vue's webpack -v error solution

<<:  MySQL table and column comments summary

>>:  Solve the problem that VMware cannot install 64-bit operating system in win10 home version

Recommend

Detailed tutorial for installing mysql5.7.21 under Windows

This article shares the installation tutorial of ...

Detailed explanation of how to connect Java to Mysql version 8.0.18

Regarding the connection method between Java and ...

Vuex implements a simple shopping cart

This article example shares the specific code of ...

Analysis and solution of flex layout collapse caused by Chrome 73

Phenomenon There are several nested flex structur...

Ubuntu installation graphics driver and cuda tutorial

Table of contents 1. Uninstall the original drive...

Detailed explanation of Linux CPU load and CPU utilization

CPU Load and CPU Utilization Both of these can re...

Summary of methods for inserting videos into HTML pages

Now if you want to use the video tag in a page, y...

How to restore a single database or table in MySQL and possible pitfalls

Preface: The most commonly used MySQL logical bac...

Does the % in the newly created MySQL user include localhost?

Normal explanation % means any client can connect...

Detailed example of HTML element blocking Flash

Copy code The code is as follows: wmode parameter...

How to encapsulate axios request with vue

In fact, it is very simple to encapsulate axios i...