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元素显示为红色背景
这个时候我觉得红色不好看,想换成黄色,修改,保存一气呵成。
结果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详细文档 %}