1. webpack-dev-server
  2. webpack-dev-middleware

webpack-dev-server = Express + webpack-dev-middleware(其实是 Express 的一个中间件)

使用 webpack-dev-server

webpack-dev-server 提供了一个简单的 Web 服务器以及使用 HRM 的功能

// package.json
// 添加 webpack-dev-server
{
  "name": "my-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch",
    "dev": "webpack-dev-server --config webpack.dev.js --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {}
}

// webpack.config.js
module.exports = {
  //...
  devServer: {
    // 告诉 webpack-dev-server 要从 dist 目录中的文件提供文件 localhost:8080
    contentBase: './dist',
    // 启用 webpack HMR
    hot: true
  }
}

配置了 devServer.hot: true webpack 会自动将 webpack.HotModuleReplacementPlugin 插件添加。

使用 webpack-dev-middleware

webpack-dev-middleware 是一个包装程序,它将通过 webpack 处理的文件发送到服务器。

它在 webpack-dev-server 内部使用,但是如果需要,它可以作为单独的软件包使用,以允许进行更多自定义设置。

// webpack.config.js
module.exports = {
  //...
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name]_[chunkhash:8].js',
    // 配置路径
    publicPath: '/',
  },
}

// server.js
const express = require('express')
const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')

const app = express()
const config = require('./webpack.config.js')
const compiler = webpack(config)

app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath
}))

app.listen(3000, function () {
  console.log('Example app listening on port 3000!\\\\n')
})

// package.json
// 添加 node server.js 脚本命令
{
  "name": "my-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch",
    "dev": "webpack-dev-server --config webpack.dev.js --open",
    "server": "node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {}
}

HMR 原理

HMR(模块热替换) 和 Live Reload(热重载)的区别:

热更新最核心的是:HMR Server 和 HMR Runtime。