webpack热更新 WDS webpack-dev-server

WDS不输出文件,而是放在内存中,配置watch会有新的IO,生成新的dist目录(生产模式下)
一般结合HotModuleReplacementPlugin使用

关于webpack-dev-server和HotModuleReplacementPlugin

webpack-dev-server
为bundle.js文件提供liveserver能力

HotModuleReplacementPlugin
主要是提供HMR的runtime,并将runtime注入到bundle.js代码中去
一旦文件修改, HMR 会将js module发送给HMR runtime,然后 HMR runtime去局部更新页面的代码

单独写两个包也是出于功能的解耦来考虑的。
简单来说就是:
webpack-dev-server提供了开启本地服务访问bundle代码的能力
hot-module-replacement-plugin 包给 webpack-dev-server 提供了热更新的能力

配置webpack-dev-server 热更新

  1. 安装webpack-dev-server
 npm i -webpack-dev-server@3.3.1 -D
  1. 配置webpack
'use strict';

const path = require('path');
const webpack = require('webpack');

module.exports = {
    // webpack-dev-server 相关配置
    plugins: [
        new webpack.HotModuleReplacementPlugin() // 为webpack-dev-server提供热更新能力
    ],
    devServer: {
        contentBase: "./dist", // 打开哪个目录的html
        hot: true
    },
    
    // 生产模式还是开发模式
    mode: 'production',
    // 入口 指定入口文件
    entry: {
        reactComp: './src/react-comp.js'
    },
    // 出口 
    output: {
        // 指定输出目录
        path: path.join(__dirname, 'dist'),
        filename: '[name].js'
    },
    // 配置loader
    module: {
        rules: [
            {
                test: /.js$/,
                use: 'babel-loader'
            },
            {
                test: /.less$/,
                use: [
                    'style-loader', // 再将样式插入到style标签中
                    'css-loader', // 将css转换成commonjs
                    'less-loader' // 将less文件转换成css文件
                ]
            },
            {
                test: /\.(png|jpg|gif|jpeg)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 40 * 1024 // 40k
                        }
                    }
                ]
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf|otf)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    }
}
  1. 配置npm脚本
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": " webpack ",
    "dev": "webpack-dev-server --open"
}
  1. 入口文件 设置module.hot.accept(重要)

WDS 默认在内容编译完成之后自动刷新浏览器,增加了HotModuleReplacementPlugin之后可以做到HMR,如果HMR失败会降级使用liveload自动刷新浏览器模式

另外HMR热更新不刷新浏览器也需要在入口文件需要进行以下配置

"use strict"

import React from 'react'
import ReactDOM from 'react-dom'
import './react-comp.less'
import dalao from './images/dalao.jpg'

// HMR 不刷新浏览器
if (module.hot){
    module.hot.accept()
}

class Search extends React.Component {
    render() {
        return (
            <div className='search-text'>
                search text devserver ?
                <img src={dalao} />
            </div>
        )
    }
}

ReactDOM.render(<Search />, document.getElementById('root'))
webpack热更新 WDM webpack-dev-middleware

WDM不刷新浏览器,而文件监听配置watch会刷新浏览器

WDM配置

Webpack热更新以及原理分析 webpack-dev-server与webpack-dev-middleware WDS WDM_bundle

WDM 原理

webpack-dev-middleware将webpack输出的文件传输给服务器
实际开发中webpack-dev-middleware用的更多,适用于定制灵活的场景

Webpack热更新以及原理分析 webpack-dev-server与webpack-dev-middleware WDS WDM_热更新_02

Webpack Complier
将js源代码编译成输出文件bundle.js

HMR Server
将热更新的文件输出给HMR Runtime

HMR Runtime
打包阶段会HMR Runtime注入到浏览器,会和服务器端建立一个连接,通常这个连接会是一个websocket会更新文件的变化

Bundle Server
提供文件在浏览器的访问,一般是通过文件目录来访问本地资源,但是Bundle Server可通过localhost+接口在浏览器端访问bundle.js,也就是说提供本地服务器形式的文件访问

bundle.js
被webpack complier编译之后由HMR Server输出到浏览器的文件

WDM 热更新流程

  1. 启动阶段
    Webpack Compiler将文件打包好传输给Bundle Server
    Bundle Server服务器 open浏览器访问bundle.js

  2. 更新阶段
    本地开发,有文件发生了变化
    Webpack Complier将文件编译打包好后发送给给HMR Server
    HMR Server 知道哪些模块发生了改变,通知浏览器端HMR Runtime 更新代码,并且不需要刷新浏览器