共计 6316 个字符,预计需要花费 16 分钟才能阅读完成。
问题形容
- 日常开发中,咱们前端在联调接口时,经常会遇到须要在
多个后端 ip 服务切换
的状况 - 举个例子,一个前端要别离和三个后端 甲、乙、丙 联调其对应的本地接口
- 前端须要先在
vite.config.js(vue.config.js)
文件中的proxy
的target
改成甲
的ip
服务地址 - 甲的本地接口联调结束当前,须要把
proxy 的 target
再改成乙
的,完了再改成丙
的,如下图:
- 那咱们就想,能不能写一个脚本,在咱们启动我的项目执行 ”npm run dev” 的时候,依据咱们的需要,主动帮忙咱们批改呢?相似于命令行的下拉框抉择的感觉那种(脚本批改代理转发,总比手动批改效率高一些)
咱们先看一下最终的效果图 gif 图
解决问题效果图
上述 gif 就能清晰的看到最终想要成果(省去了手动批改的步骤了,略微了晋升了一点点开发效率)
- 那具体如何实现的呢?
- 莫焦急,咱们先来温习(学习)一下几个常识
常识温习
1. inquirer 命令行交互工具
inquirer
是一款十分优良的命令行交互工具- 很多的框架、我的项目、程序都用到了这个工具,比方
vue-cli
的脚手架 - 如下截图:
说到这里,大家应该就明确了,inquirer
工具,能够做很多交互成果,比方:
- ‘ 输入框 ’
- ‘ 下拉框 ’
- ‘ 确认框 ’
- ‘ 明码框 ’
- 等等 …
具体大家能够去官网粗疏学习一下:inquire 官网
本例中,就是用到 ’ 下拉抉择框 ’
2. package.json 文件中增加本人的脚本
问题一:如何在 package.json 增加本人的脚本命令,并管制执行程序?
原来的脚本
"scripts": { | |
"start": "npm run dev", | |
"dev": "vite --host", | |
"build": "vite build", | |
"preview": "vite preview" | |
}, |
这个
start
脚本,相当于给npm run dev
起一个别名,即执行npm start
会调用npm run dev 命令
加上本人的脚本
"scripts": { | |
"start": "npm run dev", | |
"dev": "node ./startDevConf.js && vite --host", | |
"build": "vite build", | |
"preview": "vite preview" | |
}, |
- 咱们在原有的
vite --host
命令前,加上本人想要执行脚本文件的命令node ./startDevConf.js
,并通过&&
进行分隔 - 示意先把后面的
node ./startDevConf.js
执行结束,再去执行后边的vite --host
问题二:如何给本人写的脚本传递参数,并接管参数
比方咱们在 package.json
文件中,再加一个脚本,并附上参数helloWord
"scripts": { | |
"start": "npm run dev", | |
"dev": "node ./startDevConf.js && vite --host", | |
"build": "vite build", | |
"preview": "vite preview", | |
"params": "node ./paramsConf.js helloWord" | |
}, |
当咱们执行 npm run params
的时候,在对应的 paramsConf.js 文件
中,有两种形式能够接管:
// paramsConf.js | |
// 两种形式,拿到脚本执行传递进来的参数 | |
/** | |
* 获取脚本参数形式一:process.argv.at(-1) | |
* */ | |
console.log('process.argv 是数组 --->', process.argv); // ['C:\\Program Files\\nodejs\\node.exe', 'D:\\study\\9.6 文章 \\paramsConf.js', 'helloWord'] | |
console.log('第一项是 Node.js 过程所在的绝对路径 --->', process.argv[0]); | |
console.log('第二项是脚本文件所在的绝对路径 --->', process.argv[1]); | |
console.log('第三项脚本执行附带的参数 --->', process.argv[2]); // helloWord | |
/** | |
* 获取脚本参数形式二:process.env.npm_lifecycle_script 截取 | |
* */ | |
let fullScriptStatement = process.env.npm_lifecycle_script | |
let params = fullScriptStatement.split(' ').at(-1) // helloWord | |
console.log('通过截取也能够拿到哦', params); |
3. 几个常见的转义字符
\n
换行符\r
回车符\t
tab 缩进符\'
本义'
符\"
本义"
符
可用于给文件写入字符串内容,依据状况适当增加转义字符
4. process.env 对象
process
是程序运行过程对象的意思,其身上挂了很多属性- 比方最罕用的
process.env
- 笔者打印了一下
process.env
并截取罕用的一些属性如下:
{ | |
LANG: 'zh_CN.UTF-8', // 以后语言:中文,UTF- 8 编码 | |
NODE: 'C:\\Program Files\\nodejs\\node.exe', // node 程序安装地位 | |
NPM_CLI_JS: 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', // npm 脚手架装置地位 | |
npm_command: 'run-script', // npm 的命令 执行脚本 | |
npm_config_cache: 'C:\\Users\\user\\AppData\\Local\\npm-cache', // npm 缓存地位 | |
npm_config_home: 'https://npmmirror.com', // npm 配置镜像的源 | |
npm_config_init_module: 'C:\\Users\\user\\.npm-init.js', // npm 初始化的模块 js 文件 | |
npm_lifecycle_event: 'dev', // 以后执行的 npm 脚本的名字 npm run dev/npm run build【dev 或 build 可用于辨别开发或者生产】npm_lifecycle_script: 'node ./startDevConf.js && vite --host', // 以后执行 npm 脚本的残缺语句 | |
npm_package_json: 'D:\\study\\9.6 文章 \\package.json', // package.json 文件的地位 | |
npm_package_name: 'sou', // package.json 文件的名字 | |
npm_package_version: '0.0.0', // package.json 文件的版本 | |
NVM_HOME: 'C:\\Users\\user\\AppData\\Roaming\\nvm', // 笔者装置的 node 版本管理工具 NVM 的门路地位 | |
SESSIONNAME: 'Console', // 以后会话的类型,Console 示意是物理管制台上进行的交互式会话,而不是近程会话 | |
TERM_PROGRAM: 'vscode', // 以后应用的 vscode 的程序 | |
TERM_PROGRAM_VERSION: '1.81.1', // 以后应用的 vscode 程序的版本 | |
} |
最罕用的两个:
npm_lifecycle_event: 'dev'
// 以后执行的npm 脚本
的名字npm run dev/npm run build
【dev 或 build 可用于辨别开发或者生产】npm_lifecycle_script: 'node ./startDevConf.js && vite --host'
// 以后执行npm 脚本
的残缺语句(能够截取脚本传递的参数,如果有的话)
成果实现
第一步 package.json 增加脚本
"scripts": {"dev": "node ./startDevConf.js && vite --host",},
- 当咱们执行
npm run dev
的时候,在触发 vite 启动我的项目之前,先执行startDevConf.js 文件
中的脚本去操作跨域转发代理设置选项
第二步 应用 inquirer 配置选项
// startDevConf.js | |
import inquirer from "inquirer"; | |
async function selectServe() { | |
try { | |
const choose = await inquirer.prompt([ | |
{ | |
type: 'list', | |
name: 'serve', // 就是选中的 key | |
message: '请抉择开发环境下须要连贯的后端服务', | |
choices: [ | |
{ | |
name: '张三', | |
value: "\t\t\t\ttarget:'http://33.33.33.33:3333',", | |
}, | |
{ | |
name: '李四', | |
value: "\t\t\t\ttarget:'http://44.44.44.44:4444',", | |
}, | |
{ | |
name: '王二', | |
value: "\t\t\t\ttarget:'http://22.22.22.22:2222',", | |
}, | |
{ | |
name: '麻子', | |
value: "\t\t\t\ttarget:'http://55.55.55.55:5555',", | |
}, | |
] | |
default: choices[0].value | |
} | |
]) | |
// 假如选中的是麻子的后端服务 | |
console.log('选中的选项', choose.serve) // \t\t\t\ttarget: 'http://55.55.55.55:5555', | |
} catch (error) {console.log(` 报错了 --->: ${error}`) | |
} | |
} | |
selectServe() |
接下来,咱们只须要把选中的选项的 proxy 的 target
数据写入到 vite.config.js
文件中去即可
第三步 把选中的数据替换到 vite.config.js 文件中去即可
- 首先读取
vite.config.js
文件 - 而后找到对应的
proxy 的 target
那一行的数据 - 最初再替换一下写入
vite.config.js
文件就行了
import fs from "fs"; // vite 写法 | |
// 在读取到的 vue.config.js 文件字符串中寻找 target 行的数据 | |
function findProxyTarget(file) {let fileArr = file.split('\n') // 把文件字符串依据换行符转成数组 | |
let proxyTarget = '' // 申请转发代理那一行的数据容器 | |
for (let i = 0; i < fileArr.length; i++) { // 通过循环找到对应行 | |
if (fileArr[i].includes('target:')) {proxyTarget = fileArr[i] // 赋值一下,找到了 | |
break | |
} | |
} | |
// 把找到的这一行数据吐进来 | |
return proxyTarget // target: 'http://33.33.33.33:3333', | |
} | |
let file = fs.readFileSync('./vite.config.js', 'utf-8') // 读取 vue.config.js 文件 | |
let proxyTarget = findProxyTarget(file) // 找到 proxy 跨域代理申请转发 target 行的数据 | |
const newFile = file.replace(proxyTarget, choose.serve) // 换成咱们新选的后端服务地址 | |
fs.writeFileSync('./vite.config.js', newFile) // 写入更新 vite.config.js 文件即可 |
至此咱们的成果就实现啦
残缺代码
脚本 startDevConf.js 残缺代码
import fs from "fs"; // vite 写法 | |
import inquirer from "inquirer"; // vite 写法 | |
// const fs = require('fs') // webpack 写法 | |
// const inquirer = require('inquirer') // webpack 写法 | |
const scriptName = process.env.npm_lifecycle_event // dev build | |
console.log('process.env\n', process.env); | |
// 后端的服务选项 | |
const choices = [ | |
{ | |
name: '张三', | |
value: "\t\t\t\ttarget:'http://33.33.33.33:3333',", | |
}, | |
{ | |
name: '李四', | |
value: "\t\t\t\ttarget:'http://44.44.44.44:4444',", | |
}, | |
{ | |
name: '王二', | |
value: "\t\t\t\ttarget:'http://22.22.22.22:2222',", | |
}, | |
{ | |
name: '麻子', | |
value: "\t\t\t\ttarget:'http://55.55.55.55:5555',", | |
}, | |
] | |
// 在读取到的 vue.config.js 文件字符串中寻找 target 行的数据 | |
function findProxyTarget(file) {let fileArr = file.split('\n') // 把文件字符串依据换行符转成数组 | |
let proxyTarget = '' // 申请转发代理那一行的数据容器 | |
for (let i = 0; i < fileArr.length; i++) { // 通过循环找到对应行 | |
if (fileArr[i].includes('target:')) {proxyTarget = fileArr[i] // 赋值一下,找到了 | |
break | |
} | |
} | |
// 把找到的这一行数据吐进来 | |
return proxyTarget // target: 'http://33.33.33.33:3333', | |
} | |
async function selectServe() { | |
try { | |
const choose = await inquirer.prompt([ | |
{ | |
type: 'list', | |
name: 'serve', | |
message: '请抉择开发环境下须要连贯的后端服务', | |
choices, | |
default: choices[0].value | |
} | |
]) | |
let file = fs.readFileSync('./vite.config.js', 'utf-8') // 读取 vue.config.js 文件 | |
let proxyTarget = findProxyTarget(file) // 找到 proxy 跨域代理申请转发 target 行的数据 | |
const newFile = file.replace(proxyTarget, choose.serve) // 换成咱们新选的后端服务地址 | |
fs.writeFileSync('./vite.config.js', newFile) // 写入更新 vite.config.js 文件即可 | |
} catch (error) {console.log(` 报错了 --->: ${error}`) | |
} | |
} | |
selectServe() |
仓库地址
为了不便大家看。特提供 github 仓库地址:https://github.com/shuirongshuifu/nodeForProject
思考
- 如果
nginx
是在前端保护,咱们是不是也能够批改nginx 的 location 的 proxy_pass
呢?毕竟有时候,生产要公布好几份? - 如果进一步细分,带有
.env.development
和.env.production
文件,咱们是不是能够在其中配置一些货色,从而批改呢? - 笔者的这篇文章,抛砖引玉,心愿可能让读者们有所播种感悟 ……
正文完