文件监听是在发现源码发生变化时,不需要你手动运行 npm run build, 会自动帮你重新编译代码(即自动重新构建出新的输出文件)

webpack提供了以下3种方式,帮助你在代码发生变化后自动编译代码:
1)webpack开启 Watch Mode(监听模式);
2)webpack-dev-server;(常用!!!)
3)webpack-dev-middleware

webpack-dev-server 和 webpack-dev-middleware 都是热更新

因为webpack-dev-server是热加载(或叫热更新),是自动刷新浏览器(全部),这样很消耗性能。
所以,我们可以配置 HMR(hot module replacement,模块热替换)

webpack-dev-server 配置 hmr webpack-dev-middleware 配置 hmr

:::info 补充 - 热加载和HMR的区别
热加载是刷新整个页面;而HMR是刷新更新的部分 :::

1)开启 watch mode(监听模式)

你可以指示 webpack “watch” 依赖图中所有文件的更改。如果其中一个文件被更新,代码将被重新编译,所以你不必再去手动运行整个构建。
webpack开启监听模式,有两种方式:

  • 在package.json 文件中配置:启动webpack命令时,带上 — watch 参数;
  • 在配置 webpack.config.js 中设置 watch:true

第一种方案:启动webpack命令时,带上 —watch 参数

image.png
现在,你可以在命令行中运行 npm run watch,然后就会看到 webpack 是如何编译代码。 然而,你会发现并没有退出命令行。这是因为此 script 当前还在 watch 你的文件。
这样,我们每次修改文件的时候,保存文件并检查terminal窗口,应该就可以看到webpack自动地重新编译修改后的模块了。

你可以在webpack.config.js中配置输出文件的时候命名为[name]:[contenthash:8].js,这样文件每次有变化被保存的时候,就可以很明显地看到这些文件被重新编译了(因为输出的文件名被改了)

第二种方案:在webpack.config.js中配置(文件监听的原理分析)

image.png

缺点:为了看到修改后的实际效果,每次都需要手动刷新浏览器
那为了能够实现自动刷新浏览器的效果,接下来,我们使用 webpack-dev-server 实现此功能。

2)使用 webpack-dev-server

webpack-dev-server 为你提供了一个基本的 web server,并且具有 live reloading(实时重新加载) 功能。

① 首先,需要安装webpack-dev-server

npm install —save-dev webpack-dev-server

② 配置本地服务

相关链接:devServer配置项中的其他属性

image.png :::info 为什么要配置 contentBase ?
因为 webpack 在进行打包的时候,对静态文件的处理,例如图片,都是直接 copy 到 dist 目录下面。但是对于本地开发来说,这个过程太费时,也没有必要,所以在设置 contentBase 之后,就直接到对应的静态目录下面去读取文件,而不需对文件做任何移动,节省了时间和性能开销。 :::

static:修改配置文件,告知dev server,从什么位置查找文件 监听单个目录
image.png
以上配置告知 webpack-dev-server,将 dist 目录下的文件 serve 到 localhost:8080 下。(译注:serve,将资源作为 server 的可访问文件)

webpack-dev-server 会从 output.path 中定义的目录为服务提供 bundle 文件,即,文件将可以通过 http://[devServer.host]:[devServer.port]/[output.publicPath]/[output.filename] 进行访问。

⚠️注意:本文使用的 webpack-dev-server 版本是 3.11.2。当版本 version >= 4.0.0 时,需要使用 devServer.static 进行配置,不再有 devServer.contentBase 配置项。

③ 在 package.json中配置一个可以直接运行 dev server 的script

image.png

④ 启动本地服务:在命令行中运行 npm run start

图 文件未修改前
image.png
图 文件修改后
image.png
如果更改了任何源文件并保存它们,文件将会被重新编译(见终端)以及浏览器会自动重新刷新加载页面。
Q:但是,我们看到打包后输出的文件名却没有变化(即打包后的这些文件中的内容也没有变化),这是为什么呢?
当你启动webpack-dev-server后,原始文件作出改动后,web-dev-server会实时地编译,但是最后的编译文件并没有输出到dist文件夹中。因为实时编译后的文件都保存到了内存当中。因此很多同学使用webpack-dev-server进行开发的时候都看不到编译后的文件(重要!!!) :::info 一般情况下,output打包输出的文件都会被放在磁盘上的 :::

:::info 联想:我们平常写vue项目的时候,在开发阶段,程序员在不断改代码、调试代码、这时候我们需要实时看到最新的界面(这时的代码在webpack-dev-server的作用下,代码修改后是不断地被编译打包以及浏览器自动重新加载页面的,虽然我们在dist文件夹下看不到实时编译后的代码——实际上,我们也是不需要这些实时编译后的代码的,我们只需要看到我们的代码改动后界面的情况。到最后项目全都改好后,我们会再进行npm run build,这时候就不是开发环境了,打包后的文件也会被编译到dist文件夹下的。只要获取最后一次的这个打包文件即可)!!! :::

3)使用 webpack-dev-middleware

先简单了解它跟webpack-dev-server 的区别,具体实现监听文件变化先不管(因为用了express框架,没学过)

webpack-dev-middleware 是一个封装器(wrapper),它可以把 webpack 处理过的文件发送到一个 server。webpack-dev-server 在内部使用了它,然而它也可以作为一个单独的 package 来使用,以便根据需求进行更多自定义设置。下面是一个 webpack-dev-middleware 配合 express server 的示例。

①安装express 和 webpack-dev-middleware

npm i express webpack-dev-middleware -D

② 调整 webpack.config.js 配置文件,以去报middleware(中间件)功能能正常启用。

image.png
我们将会在 server 脚本使用 publicPath,以确保文件资源能够正确地 serve 在 http://localhost:3000 下,稍后我们会指定 port number(端口号)。

③ 自定义 express server

image.png
image.png

④ 在package.json中添加一个npm script,以使我们更方便地运行server:

image.png

⑤ 在终端执行 npm run server,然后打开浏览器,访问 http://localhost:3000。应该看到 webpack 应用程序已经运行!

image.png