webpack之文件监听及热更新

webpack 的文件监听

文件监听是在源码发生变化时,自动重新构建出新的输出文件。
webpack开启监听模式,有两种方式:

  • 启动 webpack 命令时,带上 --watch 参数。
    {
      "name": "project",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "build": "webpack",
        "watch": "webpack --watch"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
    }
    
  • 在配置 webpack.config.js 中设置 watch: true
    但是,这种方式需要每次手动刷新浏览器

webpack文件监听的原理

webpack会轮询判断文件的最后编辑时间是否变化。
某个文件发生了变化,并不会立即告诉监听者,而是先缓存起来,等 aggregateTimeout

module.exports = {
    // 默认是false,即不开启
    watch: true,
    // 只有开启监听模式时,watchOptions才有意义
    watchOptions: {
        // 默认为空,不监听的文件或者文件夹,支持正则匹配
        ignored: /node_modules/,
        // 监听到变化发生后会等300ms再去执行,默认300ms
        aggregateTimeout: 300,
        // 判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次
        poll: 1000
    },
};

热更新

使用webpack-dev-server

安装依赖

npm i -D webpack-dev-server
  • WDS 不刷新浏览器
  • WDS 不输出文件,而是放在内存中
  • 使用 Hot ModuleReplacementPlugin插件
{
  "name": "project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
}

因为WDS主要是在开发过程中使用,生产环境是用不到的,所以我们将mode改为development,然后再引入webpack自带的Hot ModuleReplacementPlugin插件,由于该插件是内置的,所以我们先引入webpack,再将插件加进来,最后还要配置一下devServer

const webpack = require('webpack');

module.exports = {
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
        contentBase: './dist', // 服务的基础目录
        hot: true   // 开启热更新
    }
};

升级填坑

但是,当你升级webpack4 ---->webpack5时,如果你的版本是webpack-cli 4*时,就会报错

Error: Cannot find module 'webpack-cli/bin/config-yargs'

{
  "webpack": "^5.36.0",
  "webpack-cli": "^4.6.0",
  "webpack-dev-server": "^3.11.2"
}

这是,因为在webpack-cli 4*中,作者删除了config-yargs,所以会报错
这里有两种解决方案:

  • 临时解决方案:将webpack-cli版本降级到webpack-cli 3*
  • 终极解决方案:修改配置文件,使用webpack serve替代webpack-dev-server也就是将配置项的 "dev": "webpack-dev-server --open"改为"dev": "webpack serve --open"

使用webpack-dev-middleware

WDM将webpack输出的文件传输给服务器,适用于灵活的定制场景。
使用这种方式,通常需要再引入一个server,一般是express或者koa

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');
})

热更新原理分析

  • Webpack Compile(webpack的编译器):将JS的源代码编译成Bundle
  • HMR Server:将热更新的文件输出给 HMR Runtime
  • Bundle server:提供文件在浏览器的访问,可以让你的文件以服务器的方式访问,比如“http://localhost:8080/search.html
  • HMR Runtime:会被注入到浏览器端的bundle.js里面,bundle.js就可以与服务器建立一个连接,通常这个连接是一个websocket,当它收到一些数据,一些回包之后,就会自动更新文件
  • bundle.js:构建输出的文件

热更新的过程

  • 启动阶段,是在文件系统里面,文件系统的一个编译,就是将初始的代码经过Webpack Compile进行一个打包,打包好以后,将打包好的文件传输给bundle server,也就是一个服务器,bundle server就可以让这个文件以server的方式让浏览器访问到
  • 更新阶段,如果本地开发时,有文件发生了变化,这时的流程是一个文件系统的变化,然后代码还是会经过Webpack Compile进行编译,编译好以后会将代码发送给HMR ServerHMR Server就可以知道哪些模块(源代码部分的模块)发生了变化,然后HMR Server就会通知HMR runtimeHMR Server是在服务端,HMR runtime是在客户端)。通常是以json的格式进行数据传输,传递给HMR runtime之后,HMR runtime就会更新我们的代码,最后我们的代码进行了改变,并且不需要刷新浏览器。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容