Vue 项目代理设置的优化

Vue 类的项目开发中项目结构基本都是类似于 Vue-cli 生成的方式,

这种方式开发中,最常用到的模式是开启代理进行 mock 调试或远程调试,

也就是使用了 Vue-cli 设置的配置 proxyTable 或者直接使用 Webpack-dev-server

提供的 proxy 选项。它是采用了 http-proxy 库,所以具体配置可查看:

https://github.com/nodejitsu/node-http-proxy#options

利用配置的这些参数我们可以做更为灵活的配置,达到更好的效果

使用需求

假设我们本地开发目前以下几种状态:

  1. 本地开发,数据使用本地的 mock Server
  2. 涉及权限接口使用本地 mock 数据,其他全部使用指定的一台远程机器
  3. 涉及权限接口使用本地 mock 数据,其他数据分接口使用不同的远程机器
  4. 所有接口使用同一台远程机器

方案

先看下经典的proxyTable 写法:

proxyTable: {
'/authui/': {
target: target,
changeOrigin: true
},
'/vendor/': {
target: target,
changeOrigin: true
}
}

其中用到了 changeOrigin 字段,主要是用于改变请求的 header。细化下需求:

  1. 本地开发:target 指向 localhost 的某个端口即可。至于 host 的验证肯定是不需要的
  2. 部分本地,其他固定的一台远程机器:需要配置 localhost 和远程的地址,远程地址多半是需要验证 host 的
  3. 同二,但机器有多台:需要手动配置多台机器
  4. 同一台远程机器,此时机器可能要严格验证,即 IP 也必须使用域名,配置好系统 host 才可使用

说明:严格验证 host 和普通验证 host 区别主要在于严格验证时,请求的 url 必须是远程机器的域名,

不能直接修改请求的 header 的 host 实现,即必须在系统 host 层面配置好域名。

分析完成具体需求好,就开始准备实现的方式。原有开发方式是执行 npm run dev,如果我们需要在命令行层面添加配置,

就需要设置为 npm run dev --param=paramvalue 的方式。对于使用 npm 的 script 脚本执行的命令,

它参数的获取无法通过 process.env 获得,而且通过 process.env.npm_config_paramName 的方式获取,

使用现成的命令行参数解析库也不是很方便,但为了省事,暂时还是使用 npm 自带的解析。

请求发起过程中需要以下几个参数:

  • host: 发起请求需要指向的 host,可能每台机器验证并不相同
  • port: 代理转发的端口
  • receiver: 用于 push 的远程地址,内包含了 ip 地址,为了省事,没有单独列出 ip 地址

然后定义代理请求自定义类型,用于配置:

  • local: 本地地址,即 localhost
  • remote: 指定的远程机器
  • 其他自定义类型:用于在配置文件中已经指定的其他类型
  • 原版本的请求,如 'http://xxx' 或者 Object 类型的配置,此类代理永不处理

根据需要,我们添加以下几个参数用于控制代理指向地址:

  1. rd: 远程机器的地址
  2. focus: 严格模式,所有自定义类型的代理转换为指定的 rd 机器,只在存在 rd 参数时可用
  3. allLocal:自定义类型代理全部指向本地
  4. host:请求发现是否使用 host,而不是 IP 地址

总结一下(序号指向前面的需求):

  • 需要使用 host 进行访问的情形:4
  • 需要更改 host:除 localhost 外都需要更改
  • 需要对已有类型进行转换:1: 需要将所有自定义类型都转换为 local, 2和3:什么也不转换,4:所有的自定义类型全部转换为 remote 类型

这么一看,貌似 host 是不需要的,它的存在主要是针对某些 机器可能需要使用 host 的方式,所以还是保留一下。

实现

逻辑理清了就很简单了,配置文件设置为:

module.export = {
rd1: {
host: 'dev1.example.com',
port: 8838,
receiver: 'http://1.1.1.1:8888/receiver'
},
rd2: {
host: 'dev2.example.com',
port: 8838,
receiver: 'http://1.1.1.1:8888/receiver'
}
}

proxyTable 配置方式

{
proxyTable: {
'/api1': 'remote',
'/api2': 'rd2',
'/auth/xx': 'local',
'/other': 'http://example.com'
}
}

获取 proxyTable 的代码:

// 处理 proxyTable
const releaseConfig = require('../config/release.conf.js') const rdConfig = releaseConfig[process.env.npm_config_rd]
const isAllRemote = process.env.npm_config_focus
const useHost = isAllRemote || process.env.npm_config_host
// 是否本机开发,本机开发 remote 会指向 local
const isAllLocal = process.env.npm_config_allLocal module.exports = function (proxy) {
const localUrl = `http://localhost:${proxy.localProxyPort}`
const defaultHost = proxy.defaultRdHost || 'dev-example.com'
const localProxyPort = proxy.localProxyPort || 8787 const finalConfig = formatReleaseConfig(releaseConfig)
const remote = finalConfig.remote || {} if (process.env.npm_config_rd) {
if (!rdConfig) {
throw new TypeError('RD 机器名称不存在,请在 config/release.conf.js 中进行配置')
} if (!remote.ip) {
throw new Error('请配置 rd 机器的 receiver')
}
} if (isAllRemote && !rdConfig) {
throw new TypeError('focus 只能在提供了 rd 名称后可设置')
} function formatReleaseConfig (config) {
const result = {}
Object.keys(config).map((key) => {
const value = config[key]
const ipMatch = (value.receiver || '').match(/:\/\/(.*?):\d/)
const ip = ipMatch && ipMatch[1]
result[key] = {
ip,
host: value.host || defaultHost,
port: value.port || '8391'
}
})
// 设置 remote
if (rdConfig) {
const ipMatch = (rdConfig.receiver || '').match(/:\/\/(.*?):\d/)
const ip = ipMatch && ipMatch[1]
result.remote = {
ip,
host: rdConfig.host || defaultHost,
port: rdConfig.port || '8391'
}
}
// 设置 local
result.local = {
ip: 'localhost',
host: 'localhost',
port: localProxyPort
}
return result
} function setProxy (proxyTable) {
const result = {}
Object.keys(proxyTable).forEach((api) => {
let type = proxyTable[api]
const isCustomType = typeof type === 'string' && !/^http/.test(type) if (isCustomType && type !== 'remote' && type !== 'local' && !finalConfig[type]) {
throw new TypeError(`代理类型${type}不正确,请提供 http 或 https 类型的接口,或者指定正确的 release 机器名称`)
} if (type === 'remote' && !finalConfig.remote) {
type = 'local'
}
if (isCustomType) {
if (isAllRemote && type !== 'remote') {
type = 'remote'
}
if (isAllLocal && type !== 'local') {
type = 'local'
}
} const targetConfig = finalConfig[type]
let target = type
if (targetConfig) {
target = {
target: `http://${useHost ? targetConfig.host : targetConfig.ip}:${targetConfig.port}`,
// 使用 host 时需要转换,其他不需要转换
headers: {
host: `${targetConfig.host}:${targetConfig.port}`
}
}
}
result[api] = target
})
return result
} return {
proxyTable: setProxy(proxy.proxyTable),
host: remote.host || defaultHost
}
}

用法

用法中需要配置两种指向:系统 host 和浏览器代理 Host。

之所以要两种 host, 本质上是因为接口使用的域名

和我们的本地访问的域名是相同的,同一域名无法指向两个地址,所以相当于对浏览器端进行了拦截。

系统 host 推荐使用 switchHost 进行切换,浏览器推荐使用 whistle 进行切换。

本地开发

host 配置:无

whistle 配置:默认的域名

127.0.0.1 dev.example.com

启动命令:

npm run dev
npm run dev --allLocal

注: 此时 proxyTable 中配置的 remote 全部转换为 local,在 allLocal 参数时将所有自定义类型转换为 local

本地 + 1 台远程

host 配置:无

whistle 配置:默认的域名

127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com

启动命令:

npm run dev --rd=rd1
npm run dev --rd=rd1 --host

注: --host 表示使用访问使用 host 而非 ip,使用时需要 host 地址

本地 + n 台远程

host 配置:无

whistle 配置:默认的域名

127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com

proxyTable 配置:

{
proxyTable: {
'/api1': 'rd1',
'/api2': 'rd2',
'/auth/xx': 'local',
'/other': 'http://example.com'
}
}

启动命令:

npm run dev

远程 1 台机器

host 配置:

1.1.1.1 dev1.example.com
1.1.1.1 dev2.example.com

whistle 配置:默认的域名

127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com

启动命令:

npm run dev --rd=rd1 --focus

总结

细挖需求,可能还有更简单的方式,在大部分情况下能够减少代码修改,

是 webpack 配置型的实现吧。当然,方式并不完美,尤其在 mac 下,

居然不能支持 --rd xx 这种形式,可以有类似的库吧,后续可以做为深入的内容

Vue 项目代理设置的优化的更多相关文章

  1. Vue首屏性能优化组件

    Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...

  2. PHPSTORM/IntelliJ IDEA 常用 设置配置优化

    PHPSTORM/IntelliJ IDEA 常用 设置配置优化 - meetrice 时间 2014-09-06 10:17:00  博客园-所有随笔区 原文  http://www.cnblogs ...

  3. Hexo + Github 个人博客设置以及优化

    原文地址: Hexo + Github 个人博客设置以及优化 一.博客设置 分类.标签云.关于等页面 在站点目录下分别执行: hexo new page "categories" ...

  4. VUE 2.x SEO 优化问题 vue-meta-info && prerender-spa-plugin 配合使用

    VUE 2.x  SEO  优化问题,以及预渲染问题 1.新建项目可以采用nuxt.js , 配置meta.以及预渲染 都很方便,官网文档都很详细: 2.对于已有项目: vue-meta-info & ...

  5. Linux安全调优1:CentOS防火墙的设置与优化

    CentOS防火墙的设置与优化 时间:2014-09-11 02:11来源:blog.csdn.net 作者:成长的小虫 的BLOG 举报 点击:4908次 一.设置主机防火墙. 开放: 服务器的:w ...

  6. vue+vue-resource设置请求头(带上token)

    前言 有这样的一个需求,后台服务器要求把token放在请求头里面 嗯一般是通过data里面通过参数带过去的 第一种方法 全局改变: Vue.http.headers.common['token'] = ...

  7. vue大型项目高性能优化----想说爱你真的不容易

    一.背景   目前公司的电子合同采用表单设计器+合同业务配合实现,做了半年多后终于上线,但是下边员工普遍反映卡顿,甚至卡死,爆栈.尤其是新增和修改合同页面,因为这部分数据量大,逻辑复杂,很容易崩溃,所 ...

  8. 第3天 IDEA 2021简单设置与优化 Java运算符 包机制

    IDEA 2021简单设置与优化 将工具条显示在上方 View–>Appearance–>Toolbar 鼠标悬停显示 File–>setting–>Editor–>Ge ...

  9. 大型vue单页面项目优化总结

    这是之前在公司oa项目优化时罗列的优化点,基本都已经完成,当时花了点心思整理的,保存在这里,方便以后其他项目用到查漏补缺. 1.打包文件中的app.js文件放入cdn,加快页面首次加载速度 2.提取公 ...

随机推荐

  1. mysql多实例运行

    1.主配置文件 [mysqld_multi] mysqld = /usr/local/mysql/bin/mysqld_safe mysqladmin = /usr/local/mysql/bin/m ...

  2. java中最常用jar包的用途说明

    java中最常用jar包的用途说明,适合初学者 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实 ...

  3. Frequent Value

    Frequent Value poj-3368 题目大意:给你n个数的数列,保证它是单调递增的.给你m个询问,每个询问是询问两个节点之间最长的连续的相等的数的长度. 注释:n,m<=100000 ...

  4. Axure RP初学2

  5. SSH三大框架整合案例

    SSH三大框架的整合   SSH三个框架的知识点 一.Hibernate框架 1. Hibernate的核心配置文件 1.1 数据库信息.连接池配置 1.2 Hibernate信息 1.3 映射配置 ...

  6. Ubuntu如何配置SSH免密登录

    前言 在搭建hadoop集群时,需要主机和副机之间实现SSH免密登录 一.环境准备 1.ubuntu两台 二.安装SSH 1.首先检测一下本机有没有安装SSH服务,如果没有任何打印说明未安装 sudo ...

  7. 【数据结构】赫夫曼树的实现和模拟压缩(C++)

    赫夫曼(Huffman)树,由发明它的人物命名,又称最优树,是一类带权路径最短的二叉树,主要用于数据压缩传输. 赫夫曼树的构造过程相对比较简单,要理解赫夫曼数,要先了解赫夫曼编码. 对一组出现频率不同 ...

  8. Struts2 之 Action 类访问 WEB 资源

    接着上次博客的内容我继续分享我所学到的知识,和自己在学习过程中所遇到问题以及解决方案.当然,如果读者发现任何问题均可以在下方评论告知我,先谢! 在 Action 中访问 WEB 资源 web 资源 所 ...

  9. 数据库(Oracle)运维工作内容及常用脚本命令

    1.系统资源状况:--内存及CPU资源  --linux,solaris,aix    vmstat 5  --说明:    1)观察空闲内存的数量多少,以及空闲内存量是否稳定,如果不稳定就得想办法来 ...

  10. pyc反编译-uncompyle2的安装及使用

    pyc反编译-uncompyle2的安装及使用 0x00 安装 1.下载并解压到安装目录 python setup.py install //安装 2.下载链接: 链接:https://pan.bai ...