Vue CLI3的图形化界面增加一个好玩的工具,快速的关闭一个网络端口,挺贴心! vue ui
傻瓜式的工具可以先用,但最终要掌握原理哦。
1.关闭端口一般方法
在Mac上关闭端口
// lsof(list open files)是一个列出当前系统打开文件的工具
lsof -i tcp:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php 54205 charlesyu 3u IPv4 0x2d201a97d7761bfd 0t0 TCP localhost:8090 (LISTEN)
// kill pid
kill 54205
// lsof -p PID 查看目录
复制代码
使用windows dos关闭端口
// 查找pid
netstat -ano|findstr 8080
// 停止端口占用
taskkill /pid 13064
复制代码
守护进程
平时我也会经常随意开启一些端口, 只要掌握怎么开关这些端口有时候是提高生产力的一种办法,下面再说 4 种常用的守护进程方式
通用守护进程
- nohup
# 忽略所有挂断(SIGHUP)信号。 后台运行,你关掉终端也会继续运行
nohup command &
nohup /root/start.sh &
复制代码
- screen
#screen是Linux窗口管理器,用户可以建立多个screen会话,每个screen会话又可以建立多个window窗口,
#每一个窗口就像一个可操作的真实的ssh终端一样。
screen -S yourname -> 新建一个叫yourname的session
screen -ls -> 列出当前所有的session
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session
复制代码
下面两个是node守护进程
- forever
# 启动
# 最简单的启动方式
forever start ./bin/www
# 指定forever日志输出文件,默认路径~/.forever
forever start -l forever.log ./bin/www
# 需要注意,如果第一次启动带日志输出文件,以后启动都需要加上 -a 参数,forever默认不覆盖原文件
forever start -l forever.log -a ./bin/www
#指定node.js应用的控制台输出文件和错误信息输出文件
forever start -o out.log -e err.log ./bin/www
# 监听当前目录下文件改动,如有改动,立刻重启应用,不推荐的做法!如有日志文件,日志文件是频繁更改的
forever start -w ./bin/www
# 重启
forever restart ./bin/www #重启单个应用
forever restart [pid] #根据pid重启单个应用
forever restartall #重启所有应用
# 停止(和重启很类似)
forever stop ./bin/www #停止单个应用
forever stop [pid] #根据pid停止单个应用
forever stopall #停止所有应用
# 查看forever守护的应用列表
forever list
复制代码
- pm2
pm2 start app.js #最简单的启用一个应用
pm2 stop app_name|app_id #停止
pm2 delete app_name|app_id #删除
pm2 restart app_name|app_id #重启
pm2 stop all #停止所有
pm2 list #查看所有的进程
pm2 status #查看所有的进程状态
pm2 describe app_name|app_id #查看某一个进程的信息
复制代码
2.Vue CLI3是怎么实现的呢?
假设你已经使用yarn命令安装了 Vue CLI3(本来想贴github源码地址,但我感觉用本地环境更好,多动手调试代码是掌握知识的好途径!)
打开文件: 你的用户目录/.config/yarn/global/node_modules/@vue/cli-ui/ui-defaults/widgets.js
module.exports = api => {
const { registerWidget, onAction, setSharedData } = api.namespace('org.vue.widgets.')
...
registerWidget({
id: 'kill-port',
title: 'org.vue.widgets.kill-port.title',
description: 'org.vue.widgets.kill-port.description',
icon: 'flash_on',
component: 'org.vue.widgets.components.kill-port',
minWidth: 2,
minHeight: 1,
maxWidth: 2,
maxHeight: 1,
maxCount: 1
})
}
setSharedData('kill-port.status', 'idle')
onAction('actions.kill-port', async params => {
const fkill = require('fkill')
setSharedData('kill-port.status', 'killing')
try {
await fkill(`:${params.port}`)
setSharedData('kill-port.status', 'killed')
} catch (e) {
console.log(e)
setSharedData('kill-port.status', 'error')
}
})
复制代码
这里是kill-port这个插件注册的位置,插件注册实现的很优雅。
pid-from-port
和 fkill
实现了关闭端口的功能。
(Ps: 记住哦!以后写脚手架的时候会用到的)
当点击【终止】按钮时,就会触发这个事件: ../.config/yarn/global/node_modules/@vue/cli-ui-addon-widgets/src/components/KillPort.vue
...
methods: {
kill () {
clearTimeout(this.$_statusTimer)
this.$callPluginAction('org.vue.widgets.actions.kill-port', {
port: this.port
})
}
}
复制代码
在事件执行之前先弄清三个问题:
-
- 这个文件中并没有$callPluginAction对象,这个对象在哪里呢?
-
org.vue.widgets.kill-port.title
从哪里来的呢?
-
- onAction 是怎么工作的?
顺藤摸瓜 找到安装入口有个methods的mixin
../.config/yarn/global/node_modules/@vue/cli-ui/src/util/plugin-action.js
export default {
install (Vue) {
Vue.mixin({
methods: {
async $callPluginAction (id, params) {
const result = await this.$apollo.mutate({
mutation: PLUGIN_ACTION_CALL,
variables: {
id,
params
}
})
return result.data.pluginActionCall ?
...
复制代码
这里的 this.$apollo.mutate 是 apollo
的更新方法,variables 是 GraphQL 中的语法。
.config/yarn/global/node_modules/@vue/cli-ui/apollo-server/api/PluginApi.js
onAction: (id, cb) => this.onAction(namespace + id, cb)
...
onAction (id, cb) {
let list = this.actions.get(id)
if (!list) {
list = []
this.actions.set(id, list)
}
list.push(cb)
}
复制代码
这里的onAction会在后面被callAction逻辑调用。
问题二有点复杂, 数据来源是通过GraphQL从CDN上拉取的。
...
"kill-port": {
"title": "Kill port",
"description": "终止占用指定端口的进程",
"input": {
"placeholder": "输入一个网络端口"
},
"kill": "终止",
"status": {
"idle": "准备好终止",
"killing": "终止进程中",
"killed": "成功终止进程!",
"error": "无法终止进程"
}
}
复制代码
org.vue.widgets.actions.kill-port
还记得上面 ?(这个emoji处返回的对象吗)return result.data.pluginActionCall
在此处有一个整理的过程
.config/yarn/global/node_modules/@vue/cli-ui/apollo-server/schema/plugin.js
Mutation: {
...
pluginActionCall: (root, args, context) => plugins.callAction(args, context),
},
复制代码
.config/yarn/global/node_modules/@vue/cli-ui/apollo-server/connectors/plugins.js
callAction 调用了 onAction 定义的逻辑,完成了关闭网络端口的功能。
async function callAction ({ id, params, file = cwd.get() }, context) {
...
return { id, params, results, errors }
}
复制代码
总结
这个功能本身并不复杂, 但Vue CLI3用了最新的技术栈,在工程化方面做的非常完美。