webpack热模块替换

519 阅读1分钟

热模块替换概念:
热模块替换只用于开发阶段,用于在运行之中,模块修改只会局部刷新,而不是整个页面进行刷新

js模块替换

index.js:

import _ from 'lodash';
import printMe from './print.js';

function component() {
    const element = document.createElement('div');
    const btn = document.createElement('button');

    element.innerHTML = _.join(['Hello', 'webpack'], ' ');

    btn.innerHTML = 'Click me and check the console!';
    btn.onclick = printMe;

    element.appendChild(btn);

    return element;
}



document.body.appendChild(component());

if (module.hot) {
    module.hot.accept('./print.js', function () {
        console.log('Accepting the updated printMe module!');
        printMe();
    });
}

print.js:

export default function printMe() {
    console.log('printMe before');
}

webpack.config.js中开启热模块:

devServer: {
        contentBase: './dist',
        hot: true
    }

然后启动webpack,点击屏幕按钮会看到在控制台打印如下:

image.png

然后修改printMe函数的输出:

export default function printMe() {
    console.log('printMe after');
}

控制台会输出启动热模块的代码:

image.png 继续点击屏幕按钮,控制台依旧输出原来的printMe函数:

image.png

热模块启动之后并没有重新刷新页面,热模块更新之后,控制台依旧保留着热模块更新之前打印出的数据:但是存在这样一个问题,热模块更新之后,点就按钮触发的依旧是原来的printMe函数,修改方法如下:
index.js部分代码替换修改如下:

let element = component();
document.body.appendChild(element);

if (module.hot) {
    module.hot.accept('./print.js', function () {
        console.log('Accepting the updated printMe module!');
        document.body.removeChild(element);
        element = component();
        document.body.appendChild(element);
    });
}

css模块替换

css热模块替换不需要额外的配置,只需要style-loader和css-loader即可。
style.css:

body {
  background: blue;
}

webpack.config.js中配置loader:

 rules: [
            {
                test: /\.css$/i,
                use: ['style-loader', 'css-loader']
            }
        ]

修改css中样式,也可以看到屏幕没有刷新。