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 &
複製程式碼
hup 終端結束會話時的訊號 參考資料
- 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上拉取的。
https://unpkg.com/vue-cli-locales@3.3.0/locales/zh.json
...
"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用了最新的技術棧,在工程化方面做的非常完美。