Electron 是一個跨平臺桌面框架,它集成了 node.js 和 chromium,因此咱們能夠藉助 node.js 實現桌面客戶端訪問操做系統資源的功能(出於安全,瀏覽器是不能夠訪問操做系統的),而 chromium 容許咱們使用前端工具HTML、JS、CSS 甚至結合 React、Vue 等渲染出用戶界面。前端
B/S 即 ‘瀏覽器/服務器’ 架構。既然 Electron 由 node.js 和 chromium 集成, 把 Electron 的渲染進程直接看成客戶端瀏覽器進程,主進程看成服務器進程,把訪問操做系統資源、讀寫文件等都放在主進程裏,而渲染進程專心用於渲染頁面和向主進程‘請求’操做資源,主進程和渲染進程之間能夠實現進程間通訊,能夠模擬瀏覽器和服務器之間的 ajax 請求。node
一個結合 Electron 的項目架構:git
下面以一個獲取 github 用戶信息和遠程倉庫的 Electron APP 爲例,用具體的代碼來展現如何實現github
渲染進程裏使用 ipcRenderer 封裝一個類 api 請求:web
// render/api.js
var electron = window.electron
var { ipcRenderer } = electron
import ipc_channel from '../const/ipc_channel'
export default {
loginGithub: ({username, password, cb}) => { // 登陸 github 以建立一個 token
// 向主進程請求登陸 GitHub
ipcRenderer.send(ipc_channel.LOGIN_GITHUB, {username, password})
// 主進程完成登陸後返回登陸響應(好比一個token)
ipcRenderer.on(ipc_channel.LOGIN_GITHUB, (e, res) => {
cb(res)
})
},
logoutGithub: ({username, password, id, cb}) => { // 退出登陸
ipcRenderer.send(ipc_channel.LOGOUT_GITHUB, {username, password, id})
ipcRenderer.on(ipc_channel.LOGOUT_GITHUB, (e, res) => {
cb(res)
})
}
}
複製代碼
主進程使用 ipcMain 將渲染進程的各個請求路由到相應的路由處理器,而且傳遞一個回調函數方便路由處理器向渲染進程發送響應:ajax
//main.js
const routes = require('./server-routes/routes')
for(let routeName in routes) {
ipcMain.on(routeName, (e, params) => {// 監聽渲染進程各個 ‘請求’
routes[routeName]({ // 路由
params, // 請求參數
cb: (respond) => {// 回調函數用於向渲染進程發送響應
e.sender.send(routeName, respond)}
})
})
}
複製代碼
路由處理器:後端
// server-routes/routes.js
var github = require('octonode')// octonode 是一個 GitHub API 封裝庫
var ipc_channel = require('../../const/ipc_channel')
const fs = require('fs')
const {getABranchContent, readLocalDir_OR_FileWithPath, readAFile} = require('./middleweres')
module.exports = {
[ipc_channel.LOGIN_GITHUB]: ({params, cb}) => {
let {username, password} = params
var scopes = {
'scopes': ['user', 'repo', 'gist'],
'note': 'admin script'
}
github.auth.config({
username,
password
}).login(scopes, function (err, id, token, headers) {
console.log(id, token)
if(!err) cb({id, token})
})
},
[ipc_channel.LOGOUT_GITHUB]: ({params, cb}) => {
let {username, password, id} = params
github.auth.config({
username,
password
}).revoke(id, function (err) {
if (err) throw err
else cb({msg: '已經退出登陸'})
})
}
}
複製代碼
用一個單獨的文件導出各個 ipc channel:api
// ipc_channel.js
module.exports = {
LOGIN_GITHUB: 'login-github-for-token', // 登陸 GitHub 以獲取 token
LOGOUT_GITHUB: 'logout-and-revoke-token', // 退出登陸並銷燬 token
GET_REPO: 'get-a-repo', // 獲取 github 上某個倉庫的內容
READ_LOCAL_PATH: 'read-local-path', // 讀取本地目錄
READ_LOCAL_FILE: 'read-local-file', // 讀取本地文件
READ_LOCAL_REPO_INFO_FILE: 'read-repo-info-file' // 讀取存儲在本地的倉庫的信息
}
複製代碼
這樣借鑑了 web 中先後端分離的思想,我的認爲能夠很清晰的分離應用的邏輯。瀏覽器
本文的素材源自我的的 Electron 小項目:github-repo-viewer安全