这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

背景

大家在日常开发中应该经常会有需要切换不同环境地址的情况。当一个项目代码切换环境地址时,vue-cli没有能够感知文件的变化,所以代理的还是旧的地址,所以通常我们需要执行npm run serve进行项目重跑,而项目重跑往往意味着长时间的等待,非常痛苦!

方案调研

事实上,其实我们只是需要重启webpack为我们启动的proxy代理服务,或许能够从webpack的代理服务插件中找到解决方法。

从webpack官网可以看到proxy服务其实是由 http-proxy-middleware提供的,或许我们能够从中找到解决方法。

初步方案

在http-proxy-middleware的配置选项中,除了我们常见的target,还有router。router返回一个字符串的服务地址,当两个选项都配置了的情况下,会优先使用router函数的返回值,只有当router的返回值不可用时,才会使用target的值。

我们可以利用这一点来重新配置我们的项目代码。参考文档在这里

// vue.config.js
const { defineConfig } = require('@vue/cli-service')
const { proxy } = require('./environments/proxy.js')
module.exports = defineConfig({
devServer:{
proxy
},
})
// proxy.js
const fs = require('fs')
const path = require('path')
const encoding = 'utf-8' const getContent = filename => {
const dir = path.resolve(process.cwd(), 'environments')
return fs.readFileSync(path.resolve(dir, filename), { encoding })
} const jsonParse = obj => { return Function('"use strict";return (' + obj + ')')() } const getConfig = () => { try {
return jsonParse(getContent('proxy-config.json'))
} catch (e) { return {} } } module.exports = {
proxy: {
// 接口匹配规则自行修改
'/api': {
// 这里必须要有字符串来进行占位
// 如果报错Invaild Url,将target改成有效的url字符串即可,如http://localhost:9001
target: 'that must have a empty placeholder',
changeOrigin: true,
router: () => (getConfig() || {}).target || ''
}
}
}
// proxy-config.json
{ "target": "http://localhost:9001" }

自此,当我们需要修改环境地址时,只需要修改proxy-config.json文件便能够实时生效,不再需要npm run serve

重点代码分析

实现代码中其实最主要的就是getContent这个方法,我们项目在每次发起http请求时都会调用router中的函数,而getContent则会通过node的fs服务,对我们的环境地址文件进行实时读取,从而指向我们最新修改的环境地址。

方案总结

在按照参考文档配置了项目代码之后,我们发现确实能够及时指向新的环境地址,再也不需要重启代码,不需要长时间的等待了。但是,我们多了两个需要维护的文件,每次我们修改环境地址时,不仅需要修改config中的api,还需要修改proxy-config.json中的target!

有没有可能在只需要修改config文件的情况下,实现代理地址动态修改呢?

方案优化

从上面的重点代码分析中,可以看到只要我们可以在router函数执行时,拿到正确的config文件中导出的api属性的值,也可以实现同样的效果!

这是不是意味着只要我们在函数中对config文件进行require请求,读取api的值,再return出去就能及时修改代理指向了呢?

没错,你会发现无论你怎么修改,函数内require取到的api永远是不变的,还是服务刚启动时的环境地址。

参考源码可以知道,这是因为我们在使用require请求文件信息时,node会解析出我们传入的字符串的文件路径的绝对路径,并且以绝对路径为键值,对该文件进行缓存

因此,如果我们在执行require函数时打断点进行观察的话,会发现require上面有一个cache缓存了已经加载过的文件。

这也恰恰说明了只要我们能够删除掉文件保存在require中的缓存,我们就能够拿到最新的文件内容,那么我们也可以据此得出我们的最终优化方案。

// vue.config.js
const hotRequire = modulePath => {
// require.resolve可以通过相对路径获取绝对路径
// 以绝对路径为键值删除require中的对应文件的缓存
delete require.cache[require.resolve(modulePath)]
// 重新获取文件内容
const target = require(modulePath)
return target
} ...
proxy: {
'/api': {
// 如果router有效优先取router返回的值
target: 'that must have a empty placeholder',
changeOrigin: true,
// 每次发起http请求都会执行router函数
router: () => (hotRequire('./src/utils/config') || {}).api || '',
ws: true,
pathRewrite: {
'^/api': ''
}
}
}

自此,我们项目修改环境地址将不在需要重启项目,也不需要维护额外的文件夹,再也不需要痛苦等待了!

本文转载于:

https://juejin.cn/post/7198696282336313400

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--你还在傻傻的npm run serve吗?快来尝尝这个!的更多相关文章

  1. 在终端输入npm run serve时出现npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test_vue_0613@1.0.0 dev: 错误的解决方法

    在vscode终端使用命令 npm run serve 的时候报错 错误原因在于由于文件 node_modules 太大,在项目上传时有些人会删掉 导致我们下载的项目中缺少这个文件 在尝试把自己项目的 ...

  2. npm run dev 和 npm run serve

    1.ERR引发的思考 创建好的 vue 项目直接执行 vue run dev 报错?运行 vue run serve 就可以启动...如下 npm run dev npm ERR! missing s ...

  3. npm run serve 报错问题 (npm ERR! code ELIFECYCLE)

    运行 npm cache clean --force删除 node_modules删除 package-lock.json运行 npm install最后 npm run serve

  4. vue工程npm run serve/start/dev启动时,node_modules文件报:Cannot read property 'range' of null 错误

    改问题是"babel-eslint"版本更新问题导致的: 给大家一个最简单粗暴的解决方案: 在项目里找到对应的工程:直接删除里面的node_modules文件夹,然后重新npm i ...

  5. npm run serve修改为npm run dev

    找到package.json文件,打开文件找到  "serve": "vue-cli-service serve"  这一行,把前面的 serve 修改 dev ...

  6. npm run dev/build/serve

    1.ERR引发的思考 npm run dev npm ERR! missing script: dev npm ERR! A complete log of this run can be found ...

  7. 三面面试官:运行 npm run xxx 的时候发生了什么?

    事情是这样的,直接开讲 面试官:npm run xxx的时候,发生了什么?讲的越详细越好. 我(心想,简单啊): 首先,DNS 解析,将域名解析成 IP 地址,然后 TCP 连接,TCP 三次握手.. ...

  8. npm run dev 报错:missing script:dev

    一.问题: 今天在运行vue项目时,在mac终端输入npm run dev,结果报错: 翻译是: npm错误:缺少script:dev npm错误:完整路径见:users/mymac/ .npm/_l ...

  9. npm run build 时的 warning

    entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit ...

  10. React项目配置npm run build命令分环境打包

    使用create-react-app脚手架创建的项目默认隐藏了webpack等配置文件信息,使用npm run eject命令暴露这些隐藏的配置文件信息 项目默认有两个环境:开发环境(npm star ...

随机推荐

  1. SP10050 POWTOW - Power Tower City 题解

    题目传送门 前置知识 扩展欧拉定理 解法 本题幂塔是有限层的,这里与 luogu P4139 上帝与集合的正确用法 中的无限层幂塔不同,故需要在到达递归边界 \(n+1\) 时进行特殊处理,对于处理 ...

  2. axios.delete传参,400错误

    我在使用axios.delete进行传参的时候,发现会报400错误 后端代码(C#) 前端代码 这样的参数请求会报400错误 后端就一个参数,前端发一个id为什么接受不到呢? 在网上找了半天,终于明白 ...

  3. PyOCD Notes

    Installation Ubuntu20.04 For Ubuntu20.04 the version in apt repository is 0.13.1+dfsg-1, which is to ...

  4. 解决邮件客户端QQ Mail及Thunderbird无法登入Outlook的问题

    最近无论是安卓手机的邮件客户端, 或者是 Ubuntu 下的 Thunderbird 都无法登入 Outlook 账号, 原因是需要开启双因素验证. 这个在 Outlook 界面上是不能直接设置的, ...

  5. Linux 下配置Oracle开机自动启动

    一./etc/oratab说明 直接使用cat 查看这个文件: gg1:/home/oracle> cat /etc/oratab # # This file is used by ORACLE ...

  6. win32 - 自动开关光驱

    #include <tchar.h> #include <windows.h> #include <mmsystem.h> // for MCI functions ...

  7. ThreadLocal的应用场景和注意事项有哪些?

    https://cloud.tencent.com/developer/article/1618405

  8. 矩池云上 git clone --recursive 出错,怎么解决

    遇到问题 有时候安装包教程里 git clone 的时候会出现以下错误: git clone --recursive https://github.91chi.fun/https://github.c ...

  9. 第134篇:解决浏览器的CORS跨域问题(CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge.)

    好家伙,   我继续尝试着将我的飞机大战使用ES6模块化分离开来,出了点问题 1.出现问题: edge,chrome等一系列浏览器,会为了安全,禁止你跨域访问 目录如下: 主程序  index.htm ...

  10. 【Azure Redis 缓存】Azure Redis 异常 - 因线程池Busy而产生的Timeout异常问题

    问题描述 StackExchange.Redis在使用线程池后,偶尔会出现Timeout awaiting response 或者 No connection is available to serv ...