窺探 Vue CLI3 UI 內置插件 - 關閉網絡端口

Vue CLI3的圖形化界面增長一個好玩的工具,快速的關閉一個網絡端口,挺貼心! vue uiphp

傻瓜式的工具能夠先用,但最終要掌握原理哦。html

1.關閉端口通常方法

在Mac上關閉端口vue

// 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關閉端口node

// 查找pid
netstat -ano|findstr 8080
// 中止端口占用
taskkill /pid 13064
複製代碼

開啓端口網段訪問權限

本機訪問git

php -S 127.0.0.1:8123
複製代碼

開放訪問github

php -S 0.0.0.0:8123
複製代碼

他人不能訪問本機服務時,首先考慮服務啓動設置是否有限制vue-cli

守護進程

平時我也會常常隨意開啓一些端口, 只要掌握怎麼開關這些端口有時候是提升生產力的一種辦法,下面再說 4 種經常使用的守護進程方式json

通用守護進程windows

  • nohup
# 忽略全部掛斷(SIGHUP)信號。 後臺運行,你關掉終端也會繼續運行
nohup command &
nohup /root/start.sh &  
nohup php -S 0.0.0.0:8123 &
複製代碼

hup 終端結束會話時的信號 參考資料api

  • 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-portfkill 實現了關閉端口的功能。

(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
      })
    }
  }
複製代碼

在事件執行以前先弄清三個問題:

    1. 這個文件中並無$callPluginAction對象,這個對象在哪裏呢?
    1. org.vue.widgets.kill-port.title 從哪裏來的呢?
    1. 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上拉取的。

unpkg.com/vue-cli-loc…

...
  "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用了最新的技術棧,在工程化方面作的很是完美。

相關文章
相關標籤/搜索