4

webpack监听代理地址修改自动重启devServer

 2 years ago
source link: https://icodex.me/2022/01/05/webpack%E7%9B%91%E5%90%AC%E4%BB%A3%E7%90%86%E5%9C%B0%E5%9D%80%E4%BF%AE%E6%94%B9%E8%87%AA%E5%8A%A8%E9%87%8D%E5%90%AFdevServer/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

webpack监听代理地址修改自动重启devServer

2022年1月5日 · One min read

本文介绍解决监听开发环境代理地址更改后自动重启webpack-dev-server的问题。

背景

日常开发经常遇到的一个问题是切换 webpack 的proxy地址,需要重启webpack-dev-server或者另开一个终端去创建一个新的webpack-dev-server实例。

为了简化这个变态的过程,于是探索借助chokidar监听系统文件的能力,来监听proxy配置文件的修改并配合webpack-dev-server的 Nodejs API达到自动重启的目的。

什么是chokidar

chokidar 是一个基于 Nodejs 的fs模块开发的监听文件的工具,跨平台,同时解决了fs模块提供的原生方法fs.watchfs.watchFile的不足。

fs.watchFile

fs.watchFile(filename[, options], listener)用来监听单个文件的变化,其采用轮询的方法,可以指定interval设置轮询时间间隔,默认是5007ms,并且当文件被访问就会触发回调函数listener

fs.watchFile的主要问题在于采用轮询的方式导致监听不精确,并且 CPU 占用高。

fs.watch

fs.watch(filename[, options][, listener])可以监听单个文件或者文件夹,可以通过eventType指定监听文件命名或者修改文件内容导致的变化,但是fs.watch API 跨平台并非 100% 一致,并且在某些情况下不可用,至于什么情况下不可用,官方文档也没解释。在 Windows 上,如果监视目录被移动或重命名,则不会触发任何事件。

chokidar.watch(paths, [options])

chokidar 解决了fs.watchfs.watchFile的不足,并且 API 简单易用且监听效率更加高效,使得 vscode 内部的监听文件也使用了这个工具。

API

配置项

chokidar.watch('file', {
// 是否持久化触发监听事件
persistent: true,
// 忽略监听的文件
ignored: '*.txt',
// 当设置为false时候,在 chokidar 初始化完成之前新增文件或者文件夹也会触发 add 和 addDir事件
ignoreInitial: false,
// 当设置成 false 时,只有 symlink 本身会被观察到变化,而不是跟随链接引用和冒泡事件通过链接的路径
followSymlinks: true,
// 监听文件或者文件夹的相对根目录
cwd: '.',
// 当设置成 true 的时候,会忽略 glob 模式的path设置,把它们当成文件名的一部分
disableGlobbing: false,
// 当设置成 false,使用 fs.watchFile 或者 fs.watch 监听文件
usePolling: false,
// 针对 fs.watchFile 设置的轮询间隔
interval: 100,
binaryInterval: 300,
alwaysStat: false,
// 设置多少层的子文件目录会被递归监听
depth: 99,
// 默认情况下,add事件将在文件首次出现在磁盘上时触发,此时还没有写入整个文件。此外,在某些情况下,在写入文件时将触发一些更改事件。在某些情况下,特别是在监视大文件时,将需要等待写操作完成,然后才能响应文件的创建或修改。将awaitWriteFinish设置为true(或true值)将轮询文件大小,保持其添加和更改事件,直到大小在可配置的时间内不变。适当的持续时间设置在很大程度上依赖于操作系统和硬件。为了准确的检测,这个参数应该相对较高,使得文件监视的响应更少。谨慎使用。
awaitWriteFinish: {
stabilityThreshold: 2000,
pollInterval: 100
},
// 指示是否监视没有读权限的文件
ignorePermissionErrors: false,
// 监听更为细节的控制,如果一个文件在被删除后的100毫秒内被重新添加,Chokidar会发出一个change事件,而不是unlink然后添加。如果默认的100毫秒不适合你,可以通过设置一个自定义值来覆盖它,以毫秒为单位。
atomic: true
});

监听事件

chokidar.watch返回一个对象,可以使用该对象的.on(event, callback)方法设置监听事件event和回调函数callbackevent类型如下:

  • add:新增文件
  • addDir:新增文件夹
  • change:文件内容变化
  • unlink:删除文件
  • unlink:删除文件夹
  • ready:扫描文件或文件夹结束,开始监听
  • error:监听程序报错

WDS 的 Nodejs API

webpack-dev-server提供 Nodejs 的 API,也就几个:

  • start:启动 WDS;
  • startCallback:启动并指定启动完的回调;
  • stop:停止 WDS;
  • stopCallback:停止并指定停止后的回调】

实现思路

在 WDS 提供的 Nodejs API 的基础上,我们利用startCallback回调注册chokidar监听文件的程序,当检测到proxy配置的文件变化后,stop WDS 并重启一个新的 WDS 实例。

// server.js
const Webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const webpackConfig = require('./webpack.config.js');
const proxy = require('./proxyConfig');
const chokidar = require('chokidar');

const compiler = Webpack(webpackConfig);
const server = new WebpackDevServer({
...webpackConfig.devServer,
proxy
}, compiler);

function createServer() {
const server = new WebpackDevServer({
...webpackConfig.devServer,
proxy
}, compiler);

server.startCallback(() => {
const watcher = chokidar.watch('./proxyConfig.js').on('change', () => {
console.log("checked dev-server proxy changes, restarting server");
server.stopCallback(() => {
watcher.close();
createServer();
});
});
});
}

createServer();
// proxyConfig.js
module.exports = {
"/api": {
target: "http://127.0.0.2"
}
}

然后开发环境的情况下使用我们的server.js程序替代 webpack 的 cli 命令,即node server.js,这样就可以了。

image-20220105224129440


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK