什么是热更新?
使用vue或者react框架开发的时,只要项目启动了,无论修改js代码还是css代码,浏览器都会更新,可能有很多童鞋会认为这就是热更新,实际上这个你看到的并不是热更新。
初始化项目
npm init
touch index.html
touch app.js
npm i webpack webpack-cli webpack-dev-server --D
注意:这里使用的是webpack 4.x,如果直接使用全局的webpack来打包,需要安装webpack-cli ,因为需要这样来打包:
webpack-cli --entry ./app.js --output build.js
这里没有全局安装webpack, 所以需要配置命令行:
package.json
"build": "webpack",
"dev": "webpack-dev-server"
这个时候如果需要启动本地服务,只需要npm run dev就可以了。但是run dev的时候会默认查找根目录下的webpck.config.js文件,下面需要配置一下该文件:
webpack.config.js
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode:'development',
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
"options": {
"presets":[
["@babel/preset-env", {
"targets": {
"browsers": [">1%"] // 编译成全球占有率大于1%的浏览器都可以识别 node
}
}]
],
}
}
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
}
]
}
]
},
plugins: [
// 处理html文件 打包压缩
new HtmlWebpackPlugin({
filename:'index.html',
template : './index.html',
inject: true, // 是否自动引入 默认true true/false
minify:{ // 压缩
removeComments:true, //删除注释
collapseWhitespace: true //删除空格,压缩
},
})
]
}
上面是一个简单的配置,通常使用的js文件,都会使用es6语法编写,所以需要将es6的语法编译成es5,这个过程需要用babel来处理。
npm install babel-loader @babel/core --save-dev
配置编译目标:
npm i @babel/preset-env --D
处理css文件:
npm i style-loader css-loader --D
处理 html文件:
npm i html-webpack-plugin --D
app.js写入es6内容:
import './app.css'
(function() {
let i = 0;
setInterval(() => {
console.log(`${i++}`)
}, 2000)
})()
启动本地服务:cnpm run dev
页面刷新
touch app.css
app.css
#app {
color: blue;
}
页面字体颜色:
修改 app.css :
#app {
color: red;
}
保存后查看页面,字体颜色已经更新为红色:
修改js文件:
setInterval(() => {
console.log(`${i++}刷新了`)
}, 2000)
保存后看打印结果,数字又从0开始了,说明浏览器刷新了,也就是重新加载了:
再修改一下html文件,文案也发生了变化,打印再次从0开始,浏览器reload了:
如果只是简单的小项目开发,简单的配置就可以满足需求;如果你的项目会比较大,或者随着需求的增加,越来越大,这个时候就会发现这种方式的弊端了。
- 项目太大,开发环境下体积比较大,每次的页面刷新耗时较长,影响开发速度。
- 只改变一点内容就刷新整个页面,有点资源浪费。
热更新
也就是webpack的模块热替换。它允许在运行时替换,添加,删除各种模块,而无需进行完全刷新重新加载整个页面,优点:
- 保留在完全重新加载页面时丢失的应用程序的状态
- 只更新改变的内容,以节省开发时间
- 调整样式更加快速,几乎等同于就在浏览器调试器中更改样式
配置devServer属性:
devServer: {
hot: true
}
devServer: {
hot: true,
hotOnly: true // 禁用页面刷新,只使用热更新
}
开启热更新后,会发现 修改css文件页面不刷新,只更新。修改js文件页面依然会刷新,如果要让修改js文件变成热更新,需要=结合插件一起:
new webpack.HotModuleReplacementPlugin()
入口文件app.js中加入下面代码,开启只更新不刷新模式:
if (module.hot) {
module.hot.accept()
}
看页面打印:
更新app.js文件,内容更新了,又开启了一个定时器,页面不是刷新,这就是模块热更新:
模块热替换还支持这样的配置:
if (module.hot) {
module.hot.accept(
'./library.js', // 可以是一个字符串或字符串数组
function() {
// 使用更新过的 library 模块执行某些操作...
})
}
注意:热更新和extract-text-webpack-plugin插件不兼容,开发环境,使用热更新,就不使用这个插件,disbale设置为true。