每次要编译代码时,手动运行 yarn run build
就会变得很麻烦。
webpack 中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码:
- webpack's Watch Mode
- webpack-dev-server
- webpack-dev-middleware
多数场景中,使用 webpack-dev-server 即可满足需要,提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。
不要使用 webpack 官方指南-开发篇中的配置,contentBase 配置太久已经失效;参考 webpack-dev-server 英文文档 和 webpack-dev-server Github 主页 文档说明
1. 安装
yarn add webpack-dev-server -D
2. 修改 webpack 配置文件
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// 指定打包模式:development、production
mode: "development",
// entry 对象是用于 webpack 查找启动并构建 bundle。其上下文是入口文件所处的目录的绝对路径的字符串。
entry: './src/index.js',
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
},
...
};
3. 添加一个 script 脚本
"scripts": {
"start": "webpack serve --config ./config/webpack.config.js",
"build": "webpack --config ./config/webpack.config.js"
},
4. 执行脚本
yarn start
服务启动后在浏览器中打开http://localhost:8080/
,即可看到红色的 Hello webpack !
,然后直接修改 index.js
中代码
element.innerHTML = "Hello webpack 2!";
切换到页面,页面直接刷新成红色的 Hello webpack 2!
,实时重新加载功能启用成功。
5. 模块热替换
模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:
- 保留在完全重新加载页面时丢失的应用程序状态。
- 只更新变更内容,以节省宝贵的开发时间。
- 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。
5.1 开启方式
- 默认开启 webpack-dev-server 默认开启 HMR,在不主动开启的情况下,从启动项目日志中可以看出
<!-- &hot=true -->
[0] multi (webpack)-dev-server/client?protocol=ws%3A&hostname=0.0.0.0&port=8080&pathname=%2Fws&logging=info&overlay=true&reconnect=10&hot=true&live-reload=true (webpack)/hot/dev-server.js ./src/index.js 52 bytes {main}
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// 指定打包模式:development、production
mode: "development",
// entry 对象是用于 webpack 查找启动并构建 bundle。其上下文是入口文件所处的目录的绝对路径的字符串。
entry: './src/index.js',
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
// 开启HMR
hot:true
},
...
};
设置 hot:true
后 webpack.HotModuleReplacementPlugin
会自动加载,所以无需像模块热替换 修改配置也可生效。
5.2 开启效果
添加1个文件:textPrint.js 。
<!--textPrint.js-->
import textPrint2 from "./textPrint2";
export default function textPrint(){
console.log("textPrint")
textPrint2()
}
修改 index.js 文件
<!--文字绑定点击事件-->
element.onclick = textPrint;
然后分别修改 textPrint.js
<!--textPrint.js-->
import textPrint2 from "./textPrint2";
export default function textPrint(){
console.log("textPrint-change")
}
点击文字,控制台直接输出修改后的结果textPrint-change
5.3 中断 HTMR
查看不开启 HTMR 效果需要中断更新流程,修改 index.js 添加代码
//添加 HMR 的 API 的回调函数,中断 HTMR
if (module.hot) {
module.hot.accept('./js/textPrint.js', function () {
console.log('Accepting the updated textPrint module!');
})
}
修改 textPrint.js : console.log("textPrint")
,控制台会有新增信息输出
<!--textPrint.js-->
[webpack-dev-server] App updated. Recompiling...
index.js:551 [webpack-dev-server] App hot update...
log.js:24 [HMR] Checking for updates on the server...
index.js:39 Accepting the updated textPrint module!
log.js:24 [HMR] Updated modules:
log.js:24 [HMR] - ./src/js/textPrint.js
log.js:24 [HMR] App is up to date.
点击文字,控制台直接输出修改后的结果还是textPrint-change
,并不是修改后的 textPrint