webpack幾種手動實現HMR的方式
目錄
- 1.前言
- 2.
- 3.基本配置
- 專案目錄
- package.on
- webpack.config.js
- main.js
- index.html
- main.
- 4.webpack-dev-server
- package.json
- dev.config.js
- 完成
- 5.webpack-dev-middleware + webpack-hot-middleware
- package.json
- dev.config.js
- 完成
1.前言
眾所周知,在webpack中使用模組熱替換(HMR),能夠使得應用在執行時,無需開發者重新npm run dev
、重新整理頁面,便能更新更改的模組,並且將效果及時展示出來,這無疑極大的改善了前端同學們的生活。
但在某些情況下,我們依然需要手動配置熱更新,這篇部落格主要分享幾種手動配置熱更新的方法。
2.GitHub
GitHub
3.基本配置
因為我們使用了vue框架來進行開發(當然也可以使用其他框架),所以,需要先進行一些配置。
專案目錄
build目錄下是webpack的配置檔案
src下面是專案程式碼
package.json
不用說,第一步肯定是安裝各種依賴,基本的依賴如下
"devDependencies": { "babel-core": "^6.26.3","babel-loader": "^7.1.4","babel-preset-env": "^1.7.0","cross-env": "^5.1.6","-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備用,這個檔案主要是作為webpack的基礎配置檔案,一般我們會區分dev(development)與build(production)兩種情況,但兩種情況的某些配置是一樣的,所以建立一個公共配置檔案可以減少程式碼量。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'); // 設定版本號 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' }
程式碼很簡單,不難理解
main.js
這個檔案主要就是建立vue例項
import 'babel-polyfill' import Vue from 'vue' import App from '../container/main.vue' new Vue({ el: '#app',render: h => h(App) })
index.html
發揮模板作用
<!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" /> <!-- 針對手持裝置優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓 --> <meta name="HandheldFriendly"www.cppcns.com content="true" /> <!-- 忽略頁面中的數字識別為電話 --> <meta name="format-detection" content="telephone=no" /> </head> <body> <div id="app"></div> </body> </html>
main.vue
主要用於測試熱載入是否成功
4.webpack-dev-server
webpack通過使用webpack-dev-server可以構建本地伺服器,相當於一個小型express,我們可以用它來實現熱載入
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" }
需要說明的是,我們通過cross-env能跨平臺地設定及使用環境變數,我們通過它來設定是development還是production
dev.config.js
在build目錄下新建dev.config.js作為dev情況下webpack的配置檔案
const webpack = require('webpack') const config = require('./webpack.config.js') // webpack4開始需要配置的變數 config.mode = "development"; config.devServer = { historyApiFallback:true,// hot引數控制更新是重新整理整個頁面還是區域性重新整理 hot: true,// inline是熱更新的一種模式,另一種是iframe inlinewww.cppcns.com: true,port: 80 } // 也一定要加上HotModuleReplacementPlugin config.plugins.push( new webpack.HotModuleReplacementPlugin() ) // 需要匯出 module.exports = config;
完成
執行npm run dev
,修改main.vue,不用重新整理瀏覽器,webapck為我們自動打包並更新。
其實可以直接在控制檯network中判斷是否啟動熱過載
webpack-dev-server使用websocket向瀏覽器傳送更新資訊
5.webpack-dev-middleware + webpack-hot-middleware
除了使用webpack-dev-serwww.cppcns.comver,我們還可以使用webpack-dev-middleware + webpack-hot-middleware來實現熱過載,不過這兩個模組都不具有伺服器的功能,我們還需要安裝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需要寫的程式碼就比較多了
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(),// 當開啟 HMR 的時候使用該外掛會顯示模組的相對路徑,建議用於開發環境 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不同,因為這裡使用的兩個模組都沒有伺服器的功能,所以我們只能用express來開啟服務
完成
執行npm run dev
,修改main.vue,不用重新整理瀏覽器,webapck為我們自動打包並更新。
也可以直接在控制檯network中判斷是否啟動熱過載
在這種情況下,webpack使用eventSource與瀏覽器溝通,與websocket雙向通訊不同的是,eventsource只能從伺服器到客戶端
到此這篇關於webpack幾種手動實現HMR的方式的文章就介紹到這了,更多相關webpack HMR內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!