Electron 是一个跨平台桌面框架,它集成了 node.js 和 chromium,所以我们可以借助 node.js 实现桌面客户端访问操作系统资源的功能(出于安全,浏览器是不可以访问操作系统的),而 chromium 允许我们使用前端工具HTML、JS、CSS 甚至结合 React、Vue 等渲染出用户界面。
B/S 即 ‘浏览器/服务器’ 架构。既然 Electron 由 node.js 和 chromium 集成, 把 Electron 的渲染进程直接当作客户端浏览器进程,主进程当作服务器进程,把访问操作系统资源、读写文件等都放在主进程里,而渲染进程专心用于渲染页面和向主进程‘请求’操作资源,主进程和渲染进程之间可以实现进程间通信,可以模拟浏览器和服务器之间的 ajax 请求。
一个结合 Electron 的项目架构:
下面以一个获取 github 用户信息和远程仓库的 Electron APP 为例,用具体的代码来展示如何实现
渲染进程里使用 ipcRenderer 封装一个类 api 请求:
var electron = window.electron
var { ipcRenderer } = electron
import ipc_channel from '../const/ipc_channel'
export default {
loginGithub: ({username, password, cb}) => {
ipcRenderer.send(ipc_channel.LOGIN_GITHUB, {username, password})
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 将渲染进程的各个请求路由到相应的路由处理器,并且传递一个回调函数方便路由处理器向渲染进程发送响应:
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)}
})
})
}
路由处理器:
var github = require('octonode')
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:
module.exports = {
LOGIN_GITHUB: 'login-github-for-token',
LOGOUT_GITHUB: 'logout-and-revoke-token',
GET_REPO: 'get-a-repo',
READ_LOCAL_PATH: 'read-local-path',
READ_LOCAL_FILE: 'read-local-file',
READ_LOCAL_REPO_INFO_FILE: 'read-repo-info-file'
}
这样借鉴了 web 中前后端分离的思想,个人认为可以很清晰的分离应用的逻辑。
本文的素材源自个人的 Electron 小项目:
https://github.com/qumuchegi/github-code-viewer
好文 推 荐
☞ 不只是同构应用(isomorphic 工程化你所忽略的细节)
☞ ES2019 新特性
☞ 愿未来没有 Webpack
好文章,我 在看