共计 1887 个字符,预计需要花费 5 分钟才能阅读完成。
背景
前端开发在调试 api 阶段,或者在 fix bug 时,常常会遇到须要一直切换代理环境的问题,很让人头大。所以一个灵便的代理逻辑能让你省去好几支烟的功夫。
上面记录一次我的项目中代理的进化计划。
初始代理计划
通过环境变量来确定代理方向环境,
const getEndpoint = () => {switch (process.env.EP) { | |
case 'qa': | |
return 'https://qa.xxx.cn'; | |
case 'online': | |
return 'https://xxx.cn'; | |
case 'dev': | |
return 'https://test.xxx.cn'; | |
default: | |
return 'http://dev2.xxx.cn'; | |
} | |
}; | |
module.exports = { | |
'/api': { | |
target: endpoint, | |
changeOrigin: true, | |
headers: {Host: new URL(endpoint).hostname | |
} | |
} | |
}; |
react-scripts
默认失效的代理文件 /src/setupProxy.js
:
module.exports = function(app) {Object.entries(apiProxyConfig).forEach(([key, value]) => {app.use(key, proxy(value)); | |
}); | |
}; |
这种形式,在开发环境启动的过程中就确定了代理环境,且启动后无奈扭转代理环境,除非批改环境变量,重启服务。当业务模块一直减少,开发环境启动的工夫也越来越长,每次须要频繁切换环境验证 bug 时,就会很耗时间。
所以须要进化一下,帮咱们省一支烟的工夫。
进化后代理计划
介绍 modheader
Chrome
浏览器扩大,次要用来 增加 / 批改 / 删除申请和响应头 , 依据 URL Pattern 来只对特定网站失效,等等用法。如下图,详见 modheader。
原理
通过浏览器对申请信息的劫持再编辑,通过读取申请头自定义增加的值来确定代理的环境,这样就把代理环境的做成动静的,可通过浏览器插件自定义切换代理环境了。
module.exports = function (app) {const map = new Map(); | |
Object.entries(apiProxyConfig).forEach(([key, value]) => {app.use(key, (req, res, next) => {const endpoint = req.headers['x-api-endpoint']; | |
if (endpoint && /^https?:\/\//.test(endpoint)) { | |
let handler = null; | |
if (map.has(endpoint)) {handler = map.get(endpoint); | |
} else { | |
handler = createProxyMiddleware({ | |
target: endpoint, | |
changeOrigin: true, | |
headers: {Host: new URL(endpoint).hostname | |
}, | |
pathRewrite: '^/api' | |
}); | |
map.set(endpoint, handler); | |
} | |
const path = req.url; | |
const prefix = '/api'; | |
// eslint-disable-next-line no-console | |
console.log(`[Proxy] /api${path} => ${endpoint}${prefix}${path}`); | |
return handler(req, res, next); | |
} | |
return next();}); | |
}); | |
}; |
多人合作
为防止不同开发者反复配置 modheader
,须要将 modheader
配置推广之,恰好 modheader
反对导出和导入,如图:
所以只需一人配置,分享链接给其他人导入即可应用。
本地 mock 数据
本地 mock
和代理环境并存。
module.exports = function (app) {const mockFile = resolve(__dirname, '../mock/mock.js'); | |
if (existsSync(mockFile)) {apiMocker(app, mockFile); | |
} | |
const map = new Map(); | |
Object.entries(apiProxyConfig).forEach(([key, value]) => {// ...}) | |
} |
后记
以上计划目前齐全能满足开发需要,且不便易用。
欢送大家评论你们业务中的前端环境代理。
更简单的代理,举荐文章如下:
一文搞定前端代理骚操作!再也不怕线上 bug 啦!
正文完