Electron is a cross-platform desktop framework that integrates Node.js with Chromium, so we can use Node.js to enable desktop clients to access operating system resources (browsers can’t access operating system for security reasons). Chromium allows us to render user interfaces using front-end tools such as HTML, JS, CSS, React, Vue, etc.

Implement B/S architecture with interprocess communication simulation

B/S stands for browser/server architecture. Since Electron is integrated with Node. js and Chromium, the rendering process of Electron is directly taken as the client browser process, and the main process is taken as the server process to access operating system resources, read and write files, etc., in the main process. The renderer process is dedicated to rendering pages and ‘requesting’ operational resources from the main process. Interprocess communication can be achieved between the main process and the renderer process, which can simulate ajax requests between the browser and the server.

A project architecture combined with Electron:

The following is an example to obtain github user information and remote warehouse Electron APP, with specific code to show how to achieve

The renderer uses ipcRenderer to encapsulate a class API request:

// render/api.js

var electron = window.electron
var { ipcRenderer } = electron
import ipc_channel from '.. /const/ipc_channel'

export default {
  loginGithub: ({username, password, cb}) = > { // Log in to Github to create a token
  // Ask the main process to log in to GitHub
    ipcRenderer.send(ipc_channel.LOGIN_GITHUB, {username, password})

 // The main process returns a login response (such as a token) after completing the login.Ipcrenderer. on(ipc_channel.login_github, (e, res) => {cb(res)})}, logoutGithub:({username, password, id, cb}) = > { // Log out
    ipcRenderer.send(ipc_channel.LOGOUT_GITHUB, {username, password, id})

    ipcRenderer.on(ipc_channel.LOGOUT_GITHUB, (e, res) => {
      cb(res)
    })
  } 
}
Copy the code

The main process uses ipcMain to route each request of the renderer process to the corresponding routing handler, and passes a callback function to facilitate the routing handler to send the response to the renderer process:

//main.js

const routes = require('./server-routes/routes')

for(let routeName in routes) {
  ipcMain.on(routeName, (e, params) => {// Listen for renderer requests
    routes[routeName]({ / / routing
      params, // Request parameters
      cb: (respond) = > {// The callback function is used to send a response to the renderer process
        e.sender.send(routeName, respond)}
      })
    })
}

Copy the code

Routing processor:

// server-routes/routes.js

var github = require('octonode')// Octonode is a GitHub API wrapper library
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: 'Logged out'}}})})Copy the code

Export each IPC channel in a separate file:

// ipc_channel.js

module.exports = {
    LOGIN_GITHUB: 'login-github-for-token'.// Log in to GitHub to obtain the token
    LOGOUT_GITHUB: 'logout-and-revoke-token'.// Log out and destroy the token
    GET_REPO: 'get-a-repo'.// Get the contents of a repository on Github
    READ_LOCAL_PATH: 'read-local-path'.// Read the local directory
    READ_LOCAL_FILE: 'read-local-file'.// Read local files
    READ_LOCAL_REPO_INFO_FILE: 'read-repo-info-file' // Read the information stored locally in the warehouse
}
Copy the code

This draws on the idea of separating the front and back ends in the Web, and I think it can clearly separate the application logic.

The material for this article comes from a personal Electron mini-project: Github – Repo-Viewer