最近换到新的项目组维护几个老项目,在debug及做需求的状态中频繁切换,每切换一次就要手动重启一次node服务,效率极低
为了节省时间,整理出以下几个
proxy更改自动重启服务
方案
以下讨论基于
vue-cli
项目
方案一:dynamic-proxy
1. 原理
- 通过json配置proxy,更改json文件内容;
- 刷新页面缓存,系统自动重定向代理;
2. 实现
-
新建
proxy/config.json
、proxy/index.js
文件 -
在
proxy/config.json
中新增内容[ { "env": "dev", "target": "https://localhost:3000", "active": true }, { "env": "test", "target": "https://localhost:4000", "active": false }, { "env": "prod", "target": "https://localhost:5000", "active": false } ]
-
在
proxy/index.js
中新增内容const fs = require('fs') const path = require('path') const json = fs.readFileSync(path.resolve(__dirname, './config.json'), 'utf-8') const config = JSON.parse(json) module.exports = () => ({ '/': { // 需要给占位内容 target: 'placeholder', ws: true, changeOrigin: true, router: function(req) { return config.find(con => con.active).target } } })
-
启动服务成功后,更改
vue.config.js
配置// 引入proxy配置 const proxy = require('./proxy/index.js') // 更改webpack的disableHostCheck,禁用host检查 config.disableHostCheck = true // 更改proxy devServer: { port: 3000, proxy: proxy() // { // '/': { // target: target, // 代理请求,解决开发时的跨域 // ws: true, // changeOrigin: true // } // } },
-
更改
proxy/config.json
的active
选项,然后清除缓存刷新页面,会发现页面proxy已经被代理到更新后的target
。
这是网上出现频率较高的方案。
But 我试了"@vue/cli-service": "^4.5.15"
以及"@vue/cli-service": "^3.3.0"
,都达不到预期效果,所以不推荐当前方案。
升级
vue-cli
会引起别的诸多依赖问题,成本过高没有继续深入验证。
方案二:PM2
1. 原理
通过使用pm2的监听重启功能,监听配置文件,当配置文件改变时,自动执行重启命令。
2. 实现
-
安装pm2npm install pm2 -g
-
package.json
在scripts
新增命令"pm": "pm2 start --watch --ignore-watch 'src' --name config -- run serve",
简单解释下上面命名行的语义:--watch
:监听当前目录,只有当前目录文件有改动,都会执行pm2 restart
;--ignore-watch 'src'
:不监听目录src
;--name config
:执行的pm2
自定义任务名称config
;run serve
:执行的脚步名称serve
,相当于npm run serve
综合理解就是:==监听非src
目录及文件,只要有文件改动就会执行npm run serve
== -
分别执行npm run pm
pm2 log
执行npm run pm
之后会显示当前执行的node进程,当比如vue.config.js
文件改动会重新启动serve,pm2 log
可以直观查看进程运行过程。
主要问题有2个
参数过多、配置相对复杂、pm2过重,让简单问题复杂化上面的脚本刚开始正常,验证时频繁出现问题
所以当前方案可行,但不推荐,有兴趣可以自行探索~
方案三:nodemon(推荐)
1. 原理
- 使用nodemon监听配置文件;
- 当配置文件改变时,自动执行重启命令;
2. 实现
-
安装
nodemon
npm install --save-dev nodemon
-
package.json
文件配置监听及重启命令在
"scripts"
字段中新增以下键值"dev": "nodemon --watch vue.config.js --exec npm run serve"
npm run serve
是原来的启动命令这样只要每次改动
vue.config.js
文件,nodemon就会自动重新执行启动命令。
下面是成功运行的截图
方案四:原生实现
但凡有第三方依赖,该依赖基本都是基于原生实现封装而来。
所以下面接着基于node原生来实现–监听配置文件更新,自动重启服务的需求。
1. 原理
- 启动服务;
- 监听配置文件变化;
- 文件内容变更,kill掉当前进程;
- 执行重启服务;
2. 实现
-
新建文件
watch.js
,并新增以下内容const fs = require('fs') const { spawn } = require('child_process') // 保存进程 let __process = null // 启动进程 function startProcess() { // TODO 这里要改成自己真实启动服务的命令 __process = spawn('yarn', ['serve']) // 打印输出到控制台 __process.stdout.on('data', (data) => { console.log(data.toString()) }) } // 重启进程 function restartProcess() { if (__process !== null) { try { // 清除进程, process.kill(__process.pid) // 杀死进程 __process.kill('SIGKILL') // 重置进程 __process = null } catch (error) { console.log('Exception: ' + error.message, 'bad') } } // 重新启动进程 startProcess() } // 启动进程 startProcess() // 监听文件变化--TODO 这里改成自己真实需要监听的文件,比如 .env.development.local fs.watch('vue.config.js', (event, filename) => { restartProcess() })
-
执行
node watch.js
-
等
yarn serve
进程完全启动后,改变vue.config.js
的proxy
选项,可以看到如下
成功自动重启服务运行的截图,然后刷新页面验证~
到此证明已经实现了我们最开始提出的需求,基于原生实现,性能好且实现过程清晰可见。
总结
这次的方案解决老项目配置更改需要手动重启服务的问题,下面分别总结下几种方案的利弊:
dynamic-proxy
:按照网上多数教程,针对proxy而言node服务能够实现无感更新proxy,可惜有可能是限于版本等原因本文未能实现;PM2
:根据官网介绍,PM2其实是非常强大进程守护工具,但对于本次需求而言pm2显得过重且配置相对复杂,所以不推荐;nodemon
:配置简单,一行命名轻松实现,理解起来也不困难,首推此方案;原生实现
:知其然才知其所以然,需求不是很复杂,原生实现其实也不难,成本而言次推当前方案;