美文网首页
Hot Module Replacement-热模块更新

Hot Module Replacement-热模块更新

作者: 5cc9c8608284 | 来源:发表于2022-04-15 12:33 被阅读0次

webpac-dev-server会帮助我们对src下面的源代码进行打包,但是打包生成的文件没有被放到dist(默认打包后的文件都放在这个文件夹中)目录下,而是放到了我们电脑中的内存里,这样可以有效地提升打包的速度,这就是webpack-dev-server隐藏的一个特性。

调试样式

我们来看一个场景:我在src目录下有一个入口文件:index.js,有一个样式文件:style.css,内容分别是:

//index.js
import './style.css';
var btn = document.createElement('button');
btn.innerHTML = '新增';
document.body.appendChild(btn);

btn.onclick = function () {
    var div = document.createElement('div');
    div.innerHTML = 'item';
    document.body.appendChild(div);
}

//style.css
div:nth-of-type(odd) {
    background: yellow;
}

在index.js文件中创建了一个button,每次点击button的时候,就会在页面上添加一个div,div的内容是item,在css文件中,获取到了索引为奇数的div,并让它的背景颜色为yellow,打包完成后,我在页面中添加了几个item,但是我觉得样式太单调了,于是我修改了style.css文件:

div:nth-of-type(odd) {
    background: yellow;
}
div:nth-of-type(even) {
    background: pink;
}

修改完成后回到页面(因为在之前我们配置了webpack-dev-server,所以现在不用我们手动去打包和刷新页面了,除非你改变了webpack的配置文件),你会发现我之前添加的内容都不见了,这样显然是不合理的,我想要的效果是我修改了css文件,页面上的样式改变而不是刷新整个页面,这个时候我们就需要用到webpack的热模块更新了。修改配置文件:

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

module.exports = {
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    entry: {
        main: './src/index.js'
    },
    devServer: {
        contentBase: './dist',
        open: true,
        port: 8080,
        //下面是新增加的两行代码
        hot: true, //这个属性是让webpack开启hot-module-replacement的功能
        hotOnly: true //这个属性表示即便是hmr的功能没有生效,也不让浏览器自动刷新
    },
    module: {
        rules: [{
            test: /\.(jpg|png|gif)$/,
            use: {
                loader: 'url-loader',
                options: {
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                    limit: 10240
                }
            }
        }, {
            test: /\.(eot|ttf|svg)$/,
            use: {
                loader: 'file-loader'
            }
        }, {
            test: /\.scss$/,
            use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        importLoaders: 2
                    }
                },
                'sass-loader',
                'postcss-loader'
            ]
        }, {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader',
                'postcss-loader'
            ]
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html'
        }),
        new CleanWebpackPlugin(['dist']),
        // 新增加的代码
        new webpack.HotModuleReplacementPlugin() //使用webpack HotModuleReplacementPlugin插件
    ],
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    }
}

package.json配置文件:

{
  "name": "lesson",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^9.3.1",
    "clean-webpack-plugin": "^1.0.0",
    "css-loader": "^1.0.1",
    "express": "^4.16.4",
    "file-loader": "^2.0.0",
    "html-webpack-plugin": "^3.2.0",
    "node-sass": "^4.10.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-middleware": "^3.4.0",
    "webpack-dev-server": "^3.1.10"
  },
  "dependencies": {
    "webpack": "^4.25.1"
  }
}

修改完成之后我们需要运行npm run start来重新打包一下代码,然后回到页面,添加几个item,再回去修改css文件,保存文件再回到页面,你会发现我们修改的样式生效了,而且刚才添加的item也都完好无损的存在于页面中。

调试js文件

在src目录下又编写了两个js文件:

//number.js
function number() {
    var div = document.createElement('div');
    div.setAttribute('id', 'number');
    div.innerHTML = 2000;
    document.body.appendChild(div);
}

export default number;

//counter.js
function counter() {
    var div = document.createElement('div');
    div.setAttribute('id', 'counter');
    div.innerHTML = 1;
    div.onclick = function () {
        div.innerHTML = parseInt(div.innerHTML, 10) + 1;
    }
    document.body.appendChild(div)

}
export default counter

//index.js
import counter from './counter';
import number from './number';

counter();
number();

number.js只负责在页面中展示一个数字,counter.js创建了一个div,div的初始内容为1,当点击div的时候,这个数字就会加一,在index.js文件中引入了两个文件,并执行了一下函数,回到页面,我们点击div,将数字加到10,然后回去修改number.js文件,将2000改成了3000:

    div.innerHTML = 3000;

如果我们没有配置热模块更新的话,页面就会被刷新,导致我们刚才点击到10的div又回到初始状态1,但是因为我们有配置webpack热模块更新,所以这个div还是显示10,你会发现,虽然这个div显示是正常的,但是我们修改的number也没有变,实际上我们希望当我们修改了number文件以后,number函数可以重新执行一次,我们就需要在index.js文件中增加一段代码:

if (module.hot) { //如果当前的项目开启了hot-module-replacement,就执行下面代码
    module.hot.accept('./number', () => { //如果number这个文件发生了变化,就执行下面的代码
        document.body.removeChild(document.getElementById('number'));//先把之前的div从页面中删掉
        number();
    })
}

这段代码的意思是假设我们开启了hot-module-replacement,如果number我呢见发生了变化,就重新执行一下这个文件,这样写了以后,我们修改了number.js文件,保存文件后回到页面,就可以看到number.js对应的div的内容改变了,counter的值也没有被刷新,这样就符合我们的预期了。
但是你会发现我们之前引入css文件的时候,就不需要这个额外的处理,其实引入css文件的时候理论上也应该写这段代码,但是css-loader已经帮我们把这段代码编写了,所以就不用我们来写(拓展:vue-loader底部也实现了这段代码,我们也不用去写这段代码,react也是)。

相关文章

  • webpcak HMR原理

    模块热替换(hot module replacement) 模块热替换(HMR - Hot Module Repl...

  • 热重载、热更新

    热更新/ 热模块替换 hot module replacement 热更新:浏览器的无刷新更新(即webpack里...

  • webpack HMR热更新

    1. 介绍 HMR(Hot Module Replacement):模块热替换,也叫模块热更新,解决自动刷新导致...

  • webpack热更新和自动刷新

    什么是webpack更新? 模块热替换(HMR - Hot Module Replacement)是 webpac...

  • webpack 热更新

    模块热替换 HMR 基本概念 模块热更新 hot module replacement: 在应用程序运行过程中替换...

  • HMR

    描述 HMR 全称 Hot Module Replacement,即模块热更新。 当代码变更时,局部替换掉部分模块...

  • webpack 热更新

    热更新,是指 Hot Module Replacement,缩写为 HMR。 如果模块发生变化,即便这个模块已经在...

  • Vue脚手架热更新技术探秘

    Vue脚手架热更新技术探秘 前言 热替换(Hot Module Replacement)或热重载(Hot Relo...

  • webpack之热更新/替换

    模块热替换(HMR)什么是模块热替换HMR(Hot Module Replacement),在应用程序运行过程中,...

  • 学习webpack【第三章-核心概念2】

    一、Hot Module Replacement 热模块替换 二、使用babel处理ES6 ———————————...

网友评论

      本文标题:Hot Module Replacement-热模块更新

      本文链接:https://www.haomeiwen.com/subject/mkncertx.html