webpack幾種手動(dòng)實(shí)現(xiàn)HMR的方式
1.前言
眾所周知,在webpack中使用模塊熱替換(HMR),能夠使得應(yīng)用在運(yùn)行時(shí),無(wú)需開(kāi)發(fā)者重新npm run dev、刷新頁(yè)面,便能更新更改的模塊,并且將效果及時(shí)展示出來(lái),這無(wú)疑極大的改善了前端同學(xué)們的生活。
當(dāng)然,目前有許多腳手架——比如vue-cli、create-react-app等,通過(guò)這些腳手架,我們可以很輕松的搭建項(xiàng)目,而且這些腳手架自動(dòng)為我們配置好了熱更新功能,從此,我們?cè)僖膊恍枰獁ebpack配置工程師了【逃】
但在某些情況下,我們依然需要手動(dòng)配置熱更新,這篇博客主要分享幾種手動(dòng)配置熱更新的方法。
2.GitHub
3.基本配置
因?yàn)槲覀兪褂昧藇ue框架來(lái)進(jìn)行開(kāi)發(fā)(當(dāng)然也可以使用其他框架),所以,需要先進(jìn)行一些配置。
項(xiàng)目目錄
build目錄下是webpack的配置文件
src下面是項(xiàng)目代碼
package.json
不用說(shuō),第一步肯定是安裝各種依賴,基本的依賴如下
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.7.0",
"cross-env": "^5.1.6",
"css-loader": "^0.28.11",
"html-webpack-plugin": "^3.2.0",
"moment": "^2.22.2",
"vue-loader": "^15.2.4",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.11.1",
"webpack-cli": "^3.0.3",
"webpack-merge": "^4.1.2"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"vue": "^2.5.16"
}
webpack.config.js
在build目錄下新建webpack.config.js備用,這個(gè)文件主要是作為webpack的基礎(chǔ)配置文件,一般我們會(huì)區(qū)分dev(development)與build(production)兩種情況,但兩種情況的某些配置是一樣的,所以建立一個(gè)公共配置文件可以減少代碼量。webpack.conf.js中代碼如下
const path = require('path');
const webpack = require('webpack');
const package = require('./../package.json');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const moment = require('moment');
// 設(shè)置版本號(hào)
const buildVersion = moment().format('YYYY-MM-DD_HH_mm_ss');
module.exports = {
entry: path.join(__dirname, '../src/pages/main.js'),
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: '/',
filename: package.name + '.js'
},
module: {
rules:[
{
test: /\.vue$/,
loader: 'vue-loader',
options: {}
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
version: buildVersion,
filename: 'index.html',
template: path.join(__dirname, '../src/pages/index.html'),
inject: 'body'
})
],
externals: {
'babel-polyfill': 'window'
},
devtool: 'source-map'
}
代碼很簡(jiǎn)單,不難理解
main.js
這個(gè)文件主要就是創(chuàng)建vue實(shí)例
import 'babel-polyfill'
import Vue from 'vue'
import App from '../container/main.vue'
new Vue({
el: '#app',
render: h => h(App)
})
index.html
發(fā)揮模板作用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>dev-server HRM</title>
<meta name="robots" content="all" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover"
/>
<!-- 顯示工具欄和菜單欄 -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- 工具欄和菜單欄樣式 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- 針對(duì)手持設(shè)備優(yōu)化,主要是針對(duì)一些老的不識(shí)別viewport的瀏覽器,比如黑莓 -->
<meta name="HandheldFriendly" content="true" />
<!-- 忽略頁(yè)面中的數(shù)字識(shí)別為電話 -->
<meta name="format-detection" content="telephone=no" />
</head>
<body>
<div id="app"></div>
</body>
</html>
main.vue
主要用于測(cè)試熱加載是否成功
4.webpack-dev-server
webpack通過(guò)使用webpack-dev-server可以構(gòu)建本地服務(wù)器,相當(dāng)于一個(gè)小型express,我們可以用它來(lái)實(shí)現(xiàn)熱加載
package.json
在安裝webpack-dev-server之后我們需要在package.json中配置script字段
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --config build/dev.config.js",
"build": "cross-env NODE_ENV=production webpack-dev-server --config build/build.config.js",
"test": "echo \"Error: no test specified\" && exit 1"
}
需要說(shuō)明的是,我們通過(guò)cross-env能跨平臺(tái)地設(shè)置及使用環(huán)境變量,我們通過(guò)它來(lái)設(shè)置是development還是production
dev.config.js
在build目錄下新建dev.config.js作為dev情況下webpack的配置文件
const webpack = require('webpack')
const config = require('./webpack.config.js')
// webpack4開(kāi)始需要配置的變量
config.mode = "development";
config.devServer = {
historyApiFallback:true,
// hot參數(shù)控制更新是刷新整個(gè)頁(yè)面還是局部刷新
hot: true,
// inline是熱更新的一種模式,另一種是iframe
inline: true,
port: 80
}
// 也一定要加上HotModuleReplacementPlugin
config.plugins.push(
new webpack.HotModuleReplacementPlugin()
)
// 需要導(dǎo)出
module.exports = config;
完成
運(yùn)行npm run dev,修改main.vue,不用刷新瀏覽器,webapck為我們自動(dòng)打包并更新。
其實(shí)可以直接在控制臺(tái)network中判斷是否啟動(dòng)熱重載
webpack-dev-server使用websocket向?yàn)g覽器發(fā)送更新信息
5.webpack-dev-middleware + webpack-hot-middleware
除了使用webpack-dev-server,我們還可以使用webpack-dev-middleware + webpack-hot-middleware來(lái)實(shí)現(xiàn)熱重載,不過(guò)這兩個(gè)模塊都不具有服務(wù)器的功能,我們還需要安裝express
package.json
同樣,在依賴都安裝好之后,需要配置package.json的script字段
"scripts": {
"dev": "cross-env NODE_ENV=development node ./build/dev.config.js",
"build": "cross-env NODE_ENV=production node ./build/build.config.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
dev.config.js
采用這種方案,dev.config.js需要寫(xiě)的代碼就比較多了
const app = require('express')();
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpackHotMiddleware = require("webpack-hot-middleware");
const path = require("path");
let config = require("./webpack.config")
config.mode = "development";
// 灰常重要
config.entry = [config.entry,'webpack-hot-middleware/client'];
config.plugins.push(
new webpack.HotModuleReplacementPlugin(),
// 當(dāng)開(kāi)啟 HMR 的時(shí)候使用該插件會(huì)顯示模塊的相對(duì)路徑,建議用于開(kāi)發(fā)環(huán)境
new webpack.NamedModulesPlugin()
)
const compiler = webpack(config);
// 使用dev-middleware與hot-middleware
const devMiddleware = webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
quiet: true
})
const hotMiddleware = webpackHotMiddleware(compiler, {
log: false,
heartbeat: 2000
})
app.use(devMiddleware);
app.use(hotMiddleware);
app.listen(80);
與webpack-dev-server不同,因?yàn)檫@里使用的兩個(gè)模塊都沒(méi)有服務(wù)器的功能,所以我們只能用express來(lái)開(kāi)啟服務(wù)
完成
運(yùn)行npm run dev,修改main.vue,不用刷新瀏覽器,webapck為我們自動(dòng)打包并更新。
也可以直接在控制臺(tái)network中判斷是否啟動(dòng)熱重載
在這種情況下,webpack使用eventSource與瀏覽器溝通,與websocket雙向通信不同的是,eventsource只能從服務(wù)器到客戶端
到此這篇關(guān)于webpack幾種手動(dòng)實(shí)現(xiàn)HMR的方式的文章就介紹到這了,更多相關(guān)webpack HMR內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼
本篇文章主要是對(duì)Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02
JS highcharts動(dòng)態(tài)柱狀圖原理及實(shí)現(xiàn)
這篇文章主要介紹了JS highcharts動(dòng)態(tài)柱狀圖原理及實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
js實(shí)現(xiàn)一個(gè)簡(jiǎn)易的計(jì)算器
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)一個(gè)簡(jiǎn)易的計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
JavaScript 加號(hào)(+)運(yùn)算符號(hào)
在一些框架中看到了類似這樣的寫(xiě)法:+new Date();感覺(jué)有些怪,查閱了相關(guān)資料和一些網(wǎng)友的幫助.對(duì)此用法解釋如下,希望對(duì)大家有所幫助,不合適的地方請(qǐng)大家指正!2009-12-12
Javascript 鼠標(biāo)移動(dòng)上去 滑塊跟隨效果代碼分享
這篇文章主要介紹了Javascript 鼠標(biāo)移動(dòng)上去 滑塊跟隨效果代碼,有需要的朋友可以參考一下2013-11-11
JS構(gòu)造一個(gè)html文本內(nèi)容成文件流形式發(fā)送到后臺(tái)
本文通過(guò)實(shí)例代碼給大家介紹了JS構(gòu)造一個(gè)html文本內(nèi)容成文件流形式發(fā)送到后臺(tái)的相關(guān)資料,需要的朋友可以參考下2018-07-07

