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文件,本质都是读取文件。

相关推荐
崔庆才丨静觅10 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606110 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅11 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment11 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊12 小时前
jwt介绍
前端
爱敲代码的小鱼12 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax