Vue-Cli/Rsbuild动态代理IP地址无需重新启动/依靠热更新

前言

在还没将vue-cli迁移到rsbuild之前呢,根据proxy.router实现了无需重启项目就能修改服务器IP的方法。现在迁移后,在rsbuild.config.mjs修改IP地址时,热更新还是有点慢,所以想把之前的实现重新应用

Vue-Cli(require)

先把Vue-Cli情况下的实现记录一下

  • 在根目录下新建service-config.js文件
js 复制代码
module.exports = {
  serverOrigin: 'https://192.168.70.28'
};
  • vue.config.js
    • require请求文件信息时,node会解析出我们传入的字符串的文件路径的绝对路径,并且以绝对路径为键值,对该文件进行缓存
js 复制代码
const hotServer = () => {
  const path = './server-config.js';
  // require.resolve可以通过相对路径获取绝对路径
  // 以绝对路径为键值删除require中的对应文件的缓存
  delete require.cache[require.resolve(path)];
  // 重新获取文件内容
  const { serverOrigin } = require(path);

  return serverOrigin || '';
};

// devServer下的proxy
proxy: {
  '/audit-apiv2': {
    secure: false,
    // target: 'that must have a empty placeholder',
    target: 'http://127.0.0.1:10086',
    router: () => hotServer(),
    onProxyReq(proxyReq) {
      // 绕过后端的csrf验证
      proxyReq.setHeader('referer', hotServer());
    }
  },
}
  • vue-cli 的代理是使用的http-proxy-middleware包,所以proxy选项的配置也是基于这个包的配置。在proxy配置选项中有两个属性target以及router。其中target是默认的代理地址。而router可以return一个字符串服务地址,那么当两个选项都配置了时,http-proxy-middleware在解析配置时,会首先使用router函数的返回值,当router的返回值不可以用时,那么就会fallbacktarget
  • 项目在每次发起http请求时都会调用router中的函数,对我们的环境地址文件进行实时读取,从而指向我们最新修改的环境地址。

Rsbuild(jiti)

查了rsbuild的proxy实现方式后,发现和webpackproxy的实现是差不多的,都是使用了http-proxy-middleware包,描述也和webpack一致,所以我直接原封不动的迁移过来了

  • 在迁移完代码后,我对其进行验证发现,并没有生效,修改service.config.jsserverOrigin的值并不生效
  • hotServer函数中打印
js 复制代码
const hotServer = () => {
  const path = './server-config.js';
  // require请求文件信息时,node会解析出我们传入的字符串的文件路径的绝对路径,并且以绝对路径为键值,对该文件进行缓存
  // require.resolve可以通过相对路径获取绝对路径
  // 以绝对路径为键值删除require中的对应文件的缓存
  console.log('require', require);
  console.log('require.cache', require.cache);
  delete require.cache[require.resolve(path)];
  // 重新获取文件内容
  const { serverOrigin } = require(path);
  console.log(serverOrigin, 'serverOrigin');

  return serverOrigin || '';
};
  • 打印内容如下:
js 复制代码
[Function: jiti] {
  resolve: [Function: _resolve] { paths: [Function: paths] },
  cache: {},
  extensions: {
    '.js': [Function (anonymous)],
    '.json': [Function (anonymous)],
    '.node': [Function (anonymous)]
  },
  main: undefined,
  transform: [Function: transform],
  register: [Function (anonymous)],
  evalModule: [Function: evalModule],
  import: [Function (anonymous)]
}
  • resolve :用于动态解析模块路径(类似 Node.js 的 require.resolve)。

  • cache :JITI 的模块缓存,类似于 Node.js 的 require.cache,但独立于 Node.js 的缓存机制。

  • extensions :定义可被加载的文件类型及其对应的处理器(.js, .json, .node 等)。

  • transform:即时编译模块(例如 TS 转译为 JS)。

  • register :注册自定义模块加载逻辑(例如扩展 .ts 支持)。

  • evalModule:直接对模块代码进行动态求值。

  • 发现,这打印的是一个jiti,而且cache是个空对象。难怪不生效,service-config.js并不在缓存中。

什么是jiti

ITI 是一个轻量级动态模块加载工具,支持 CommonJS 和 ES 模块的动态加载,且在运行时进行编译和解析。以下是 JITI 的主要特性:

  1. 替代 Node.js 的 require JITI 提供类似 require 的 API,但它在内部可能对模块进行即时编译(尤其是 TS 或 ES Module),所以你看到它不是原生的 require

  2. 缓存管理

    • JITI 提供自己的缓存机制(如 jiti.cache),和 Node.js 的 require.cache 不同。
    • 你可以通过 jiti.cache 来管理模块缓存。
  3. 扩展支持

    • JITI 支持多种扩展(.js, .json, .ts 等),可以动态解析不同格式的模块。
  4. 增强功能

    • 支持动态 import
    • 提供更灵活的模块解析机制(如内联编译 TypeScript)。

在我的 Rspack 配置中,require 并不是传统 Node.js 的 require 函数,而是被替换为了 JITI("Just-In-Time-Interpreter")。

如果使用 JITI,模块的缓存不会存储在 require.cache 中,而是在 jiti.cache 中。因此,你无法通过传统的 delete require.cache[require.resolve(...)] 来清除缓存,而需要清理 jiti.cache

那么,我们需要安装jiti

sh 复制代码
npm install jiti

删除cache缓存

  • rsbuild.config.mjs文件中
mjs 复制代码
const jiti = require('jiti')(__dirname);

const hotServer = () => {
  const path = './server-config.js';
  // require.resolve可以通过相对路径获取绝对路径
  // 以绝对路径为键值删除require中的对应文件的缓存
  delete jiti.cache[require.resolve(path)];
  // 重新获取文件内容
  const { serverOrigin } = require(path);

  return serverOrigin || '';
};
  • 其余的代码照旧使用hotServer,如此一来,只需要修改service-config.js文件中的IP地址即可,这样省略了热更新的时间,也能提升一点效率。

通用方法(fs文件读取)

使用文件读取的方式,这样就不需要再安装jiti

  • rsbuild.config.mjs
js 复制代码
import fs from 'fs';

const hotServer = () => {
  const path = './server-config.json';
  const content = fs.readFileSync(path).toString();
  const { serverOrigin } = JSON.parse(content);
  return serverOrigin || '';
};
  • service-config.json
json 复制代码
{
  "serverOrigin": "https://192.168.70.203"
}

总结

以上三种方式都能实现,在修改IP地址后,无需重新启动项目或等待热更新,直接刷新浏览器页面即可。

当然,service-config.json中的serverOrigin也可以抽取到.env文件,本质都是读取文件。

相关推荐
王先生技术栈30 分钟前
思维导图,Android版本实现
java·前端
悠悠:)1 小时前
前端 动图方案
前端
星陈~1 小时前
检测electron打包文件 app.asar
前端·vue.js·electron
Aatroox1 小时前
基于 Nuxt3 + Obsidian 搭建个人博客
前端·node.js
每天都要进步哦1 小时前
Node.js中的fs模块:文件与目录操作(写入、读取、复制、移动、删除、重命名等)
前端·javascript·node.js
仿生狮子2 小时前
CSS Layer、Tailwind 和 sass 如何共存?
javascript·css·vue.js
在路上`2 小时前
vue3使用AntV X6 (图可视化引擎)历程[二]
javascript·vue.js
brzhang3 小时前
开源了一个 Super Copy Coder ,0 成本实现视觉搞转提示词,效率炸裂
前端·人工智能
diaobusi-883 小时前
HTML5-标签
前端·html·html5
我命由我123453 小时前
CesiumJS 案例 P34:场景视图(3D 视图、2D 视图)
前端·javascript·3d·前端框架·html·html5·js