1. preface

In this paper, readers can understand the development and basic concepts of the electron project in a short time by writing a small project starting from 0

  1. Environment to prepare

NodeJs use Taobao image or company image installation electron to check whether the installation is successful official Demo NPM install & NPM start


  1. Project initialization

Create a react-electron project using create-react-app and electron

Directory initialization

  1. Initialize a react-app and manually add the main.js file
  2. At this point, the directory structure is as follows (described later in preload.js)



3. Add “main”: “./main.js” to package.json



4. Add “electronic-start “: “electron.” to the startup script.

5. The directory is ready

Main.js (you can copy main directly from the official demo)

const {app, ipcMain, BrowserWindow} = require('electron') const debug = require('electron-debug') const path = require('path') function createWindow () { const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: Path.join (__dirname, 'preload_render. Js '), javascript: true, // javascript Boolean (Optional) - Enable javascript support. The default value is true. NodeIntegration: true, // nodeIntegration Boolean (Optional) - Enable Node Integration. The default is false. WebSecurity: False, / / when set to false, it will disable the same-origin policy (usually used to test the website), if this option is not set by the developer, will put allowRunningInsecureContent set to true. Default is true contextIsolation: // Boolean (optional) - Run electron in a standalone JavaScript environment API and the specified Preload script. The default is true. } }) mainWindow.loadURL('http://localhost:3000') debug.openDevTools(mainWindow) } ipcMain.on('asynchronous-message', (event, arg) => { console.log('main:', arg) // prints "ping" event.reply('asynchronous-reply', 'pong' + arg) }) ipcMain.handle('handle-message', async () => { const result = await Promise.resolve('123'); return result; }) app.whenReady().then(() => { createWindow() app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', function () { if (process.platform ! == 'darwin') app.quit() })Copy the code

Start the project

NPM run start Starts the React project NPM run electron-start Starts the electron main process

Then you can see our local client loading the React page

At this point, the project initialization is successful!

This concludes the 💥 Hello World section

  1. Electron introduces the basic concept of electron

Main process (main.js)

Each Electron application has a single main process that serves as the entry point for the application. The main process runs in a Node.js environment, which means it has the require module and the ability to use all node.js apis.

Window process

The window created using BrowserWindow

You need to configure window sizes, controls, Web-related configurations, and so on

Application life cycle

The main process can also control the life cycle of your application through Electron’s APP module.

For example, when initialization is complete –> Ready

Before closing –> before-quit and so on

Different events differ on Mac and Windows

The native API

The API documentation

Renderer process

Each BrowserWindow has a separate Render process that communicates with the main process through the ipcRenderer module

Preloading scripts (corresponding to preload_render.js file)

Each render process takes precedence over the script loaded by the web content, has access to the Node API, shares the Window, but cannot inject things into the window

  1. Communication between main process and renderer process

Main process (communication part of main.js)

Use ipcMain to listen, and use two examples: on and Handle

const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.reply('asynchronous-reply', 'pong')
})

ipcMain.handle('handle-message', async () => {
  const result = await Promise.resolve('123');
  return result;
})
Copy the code

Renderer (app.js) (business component, some data communicates with main)

Here you send a message to the main process every time you click, and then change the view when you receive the return

import React, { useCallback, useEffect, useState } from 'react'; import logo from './logo.svg'; import './App.css'; const { ipcRenderer } = window.require('electron') const App = () => { const [clickTime, setClickTime] = useState(0); const [echo, setEcho] = useState(''); const sendMsg = useCallback(() => { ipcRenderer.send('asynchronous-message', clickTime) }, [clickTime]); useEffect(() => { ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log('renderer:', arg) setClickTime((clickTime) => clickTime += 1) setEcho(arg) }) ipcRenderer.invoke('handle-message').then((res) => { console.log('handle-message:', res) }) }, []) return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p  onClick={sendMsg}> click to send Msg </p> <p> echo : {echo} </p> </header> </div> ); } export default App;Copy the code

Start the renderer process and the main process separately

The results of

Complete the communication between App and Main

Main and Renderer messages printed

💥 At this point, simple communication between master and renderer processes is complete


  1. Package the project and generate the installation file

Installing the Packing Toolelectron-builder

  1. First of all,npm run buildPackage app.js generationbuildfolder
  2. changemain.jsThe path resource referenced in
LoadURL mainwindow. loadURL('http://localhost:3000') // loadFile is now used to load files mainWindow.loadFile('./build/index.html')Copy the code
  1. To execute the electron builder — MAC, you need to configure the package in the package (or configure the JSON file separately)

Windows and MAC configurations differ

"build": { "productName":"electronDemo", "appId": "tzz.electron", "copyright":"xxxx", "directories": { "output": Dist "}, "asar": false, "MAC ": {"icon":" SRC /icon.png"}, "extends": null, "dist" : "dist"}, "asar": false, "MAC ": {"icon":" SRC /icon.png"}, "extends": null, ["build/", "main.js", "package.json", "preload.js"] }Copy the code
  1. Installation output folderdistDMG file, open app
  2. To see the results we want

At this point the development of the whole project is over, can be used normally on the computer