跳到主要内容

webpack4.0学习总结(四)

webpack的devServer热更新以及HMR局部热更新

DevServer

DevServer可以起一个本地服务并且实现代码的热更新。可以省去我们每次更新代码后重启服务额操作。

npm i webpack-dev-server -D

配置文件

package.json

"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
},

webpack.config.js

devServer: {
contentBase: './dist',
open: true, // 自动打开浏览器
port: 3001, // 服务器端口号
},

我们之后只需要使用npm run start就可以把服务跑起来了,之后只要改动代码就会自动更新了,开发效率提高了很多有没有😝

devServer更多配置内容

HMR实现局部热更新

HMR(Hot Module Replacement)

当我们更改了部分文件后,我们发现webpack-dev-server帮我们重新渲染所有内容,假如我只改动了一小部分,只想更新这一部分内容就可以用了使用HMR来实现了。

说再多不如看一个例子

index.js

import './index.css';

var root = document.getElementById('root');

root.innerHTML = '<button id="btn">add new block</button>';

document.getElementById('btn').onclick = function() {
var newBlock = document.createElement('p');
newBlock.innerHTML = 'new Block';
root.append(newBlock);
}

index.css

p {
width: 100px;
}
p:nth-child(6) {
background: red;
}

这里例子就是点击按钮添加一个p元素,第6个p元素显示为红色背景

这个时候我觉得红色不好看,想换成黄色,修改,保存一气呵成。

image-20200518122346853

结果webpack-dev-server给我全部重新渲染了,我还要再点6下才能看到效果,这里如果是1000(虽然不太可能)呢,那我岂不是要点1000下😱。

这个时候配置HRM就可以轻松解决这个问题了。

只需要再webpack.config.js中配置

devServer: {
contentBase: './dist', // Tell the server where to serve content from
open: true, // 自动打开浏览器
port: 3001, // 服务器端口号
hot: true, // 开启HRM
},

搞定😎,不过这里由于有css-loader帮我们做了一些更新的任务,所以我们并没有写过多的代码。那如果没有css-loader处理那怎么办?下面看一下具体配置。

{% tabs 3%}

import Counter from './counter'
import Number from './number'

Counter();
Number();
function Counter() {
var root = document.getElementById('root');
var counter = document.createElement('div');
counter.innerHTML = 0;
counter.onclick = function () {
counter.innerHTML = parseInt(counter.innerHTML, 10) + 1;
}
root.append(counter);

}

export default Counter;
function Number() {
var root = document.getElementById('root');
var data = document.createElement('div');
data.setAttribute('id', 'number');
data.innerHTML = '2000';
root.append(data);
}

export default Number;

{% endtabs %}

可以看到当我一改变number,counter中的状态又重新渲染变成0了😩。

这里我们就要通过一部分代码来处理一下了(css-loader就是帮我们完成了这部分工作)

import Counter from './counter'
import Number from './number'

Counter();
Number();

if (module.hot) { // 如果开启HMR
module.hot.accept('./number.js', () => {
var root = document.getElementById('root');
root.removeChild(document.getElementById('number'));
console.log('number is updated');
Number();
// 一旦number.js文件改变,进行一系列处理
})
}

{% note link, HMR详细文档 %}