React + Electron development record (screenshot literacy)

React + Electron development record (screenshot literacy)

Preface

ElectronIs Githubdeveloped, the desktop is a cross-platform application development framework, using HTML css jssoftware technology development that can be installed above the desktop, allowing front-end staff HTML css jstechnical development of cross-platform desktop software can be installed.

The development tools VSCode Atomthat we often use on the front end are all Electrondeveloped, because I was curious, I tried the introduction of development and recorded it.

Environment setup

Because it is used, reactI directly use the official scaffolding create-react-app, and the related environment nodewill not be repeated (Baidu has it all). Mainly record the integrated Electronconfiguration development environment.

  1. Installation Electrondependencies

    npm i electron --dev
     
  2. Add the Electronnecessary startup files

    In the publiccreation folder electron.jsfile

    const { app, BrowserWindow } = require('electron')
    
    let mainWindow
    function createWindow () {
    //
     mainWindow = new BrowserWindow({
         width: 800, 
         height: 600, 
         webPreferences: {
             nodeIntegration: true,//  Nodejs
         }})
    
    // html 
     process.env.NODE_ENV === 'development' ? 
         mainWindow.loadURL('http://localhost:3000/')
         :
         mainWindow.loadURL(`file://${__dirname}/index.html`)
       
      // 
        mainWindow.webContents.openDevTools()
     
      // window .
       mainWindow.on('closed', function () {
         mainWindow = null
       })
     }
     
    //  Electron  
     app.on('ready', createWindow)
     
    // .
     app.on('window-all-closed', function () {
      //macOS  `Cmd + Q`  , .
       if (process.platform !== 'darwin') {
         app.quit()
       }
     })
     
     app.on('activate', function () {
       //macOS Dock , 
       if (mainWindow === null) {
         createWindow()
       }
     })
    
     
  3. Configure Electronentry and run development environment

    package.jsonAdd in the file, and add scriptconfiguration

    "main": "public/electron.js",
    "scripts": {
      "start": "react-scripts start",
      "build": "react-scripts build",
      "test": "react-scripts test",
      "eject": "react-scripts eject",
      "electron:dev": "cross-env NODE_ENV=development electron ."
      }
     

    Then npm startit npm run electron:devcan be displayed in the interface after starting up and running

  4. Optimize the development start command

    Install packages that enable multiple monitoring services concurrentlyat the same time to wait-onwait

    npm i concurrently wait-on -D
     

    Then modify scriptthe electron:devcommand under the file

    "electron:dev": "concurrently/"cross-env BROWSER=none yarn start\"/"wait-on http://localhost:3000 && cross-env NODE_ENV=development electron ./""
     

    In this way, we directly run this command to open the Electrondevelopment environment directly to open the application, eliminating the need to run two commands directly.

Main process and rendering process

  1. Introduction

    ElectronRun package.jsonthe mainscripting process is called the primary process. The script running in the main process creates a web page to display the user interface. An Electronapplication always has one and only one main process.

    Since it is Electronused Chromiumto display web pages, Chromiumthe multi-process architecture is also used. Each Electronweb page running on its process called rendering process.

    In ordinary browsers, web pages usually run in a sandbox environment and cannot access the native resources of the operating system. However, Electronusers in Node.jsthe APIcan and some of the underlying operating system interaction with the support page.

-------- From the official website

  1. Characteristics of different processes:

    • Main Process:

      • Can be used to interface with the systemElectron API
      • Create a rendering process- Renderer Process
      • Full supportNode.js
      • One and only one
    • Renderer Process:

      • There can be multiple, each corresponding to a window
      • Each is a separate process
      • Full support Node.js&DOM API
      • Can use part ElectronofAPI

    The main process uses the BroswerWindowinstance to create a web page. Each BroswerWindowinstance runs a web page in its own rendering process. When an BroswerWindowinstance is destroyed, the corresponding rendering process will also be terminated. The main process manages all pages and their corresponding rendering processes. Each rendering process is independent of each other and only cares about their own web pages. As the management of native on the page where GUIresources are very dangerous and likely to cause resource leaks, so the page face call GUI-related APIsare not allowed. If you want to use on the page in GUIthe operation, which corresponds to the rendering process must communicate with the primary process, the main process requests for related GUIoperations. In Electron, we offer between the primary process and rendering process for communication ipcmodule. And there is also a remote process call style communication module remote.

Communication between processes

Introduced in the rendering Electron(that is, the sub-page referred to)

const { ipcRenderer } = window.require('electron')

ipcRenderer.send('emit', { name: 'electron' })// 


 

In the main thread, it is also related to the introduction of ipcMainmodules. This project refers to mine.electron.js

const { ipcMain  } = require('electron')
 ipcMain.on('capture-screen', (e, data) => {
     console.log(data)// data  
 })
 

The communication between the main thread and the rendering process here is more like a monitoring mode, one sendby one on.

BrowserWindow Api usage record

Because this APIwill be used, record some main parameters

const { BrowserWindow } = require('electron')
let mainWin

mainWin = BrowserWindow({
        width: 1080,// 
        height: 800,// 
        backgroundColor: "#292B35",//
        fullscreenable: false,// 
        transparent: false,//
        resizable: false, // 
        alwaysOnTop:true,// 
        hasShadow: false,//
        frame: false,// 
        x: 0,//x 
        y: 0,//y 
       //titleBarStyle: "hidden",
        darkTheme:true,// 
        show:false,// 
        title: '',// 
        icon: path.join(__dirname, '../win_favicon.ico'),// ico  windows 
        webPreferences: {
            nodeIntegration: true,//  Nodejs
    }})

 

Here I want to talk about titleBarStylethis parameter

This parameter is provided to customize the title bar of the form

For the time being, I just found the macnext effect.

More detailed information APIcan be found on the official website. Official website BrowserWindow related Api

Tray Api usage record

Because the pallet is used in the project, hereby record the difference between the encounter windowsand the macnext.

Incorporated in the main thread Traymodule, and used to create (note that in appthe readyafter creation) when the Electroncompletion of initialization is completed

const { app, Menu, Tray, ipcMain  } = require('electron')

let mainTray = null

//  
  if(require('os').platform() === 'win32') {// ico window 
    mainTray = new Tray(path.join(__dirname, 'win_favicon.ico')); //windows 
  } else {
    mainTray = new Tray(path.join(__dirname, 'logo_normal.png'));//mac 
    mainTray.setPressedImage(path.join(__dirname, 'logo_pressed.png'))//mac 
  }
  
 // Menu Api 
   const contextMenu = Menu.buildFromTemplate([
     {label: ' ', click: () => {captureSceen()}},
     {label: ' ', click: () => {uploadImgDialog()}},
     {label: ' PDF ', click: () => {uploadPdfDialog()}},
     {label: ' ', click: () => { mutileWin.show()}},
     {label: ' ', click: () => {settingWin.show()}},
     {label: ' ', click: () => {redcordWin.show()}},
     {label: ' ', click: () => {
       //mac Tray destroy mac  
        require('os').platform() === 'win32' ?
            mainTray.destroy()
            :
            MacShowResultWin.destroy()
          
          mutileWin.destroy()
          settingWin.destroy()
          redcordWin.destroy() 
          app.quit()
     }},//
   ])
   
mainTray.setContextMenu(contextMenu)// 

// `windows`   
mainTray.on('click', ()=>{//
  mutileWin.isVisible() ? mutileWin.hide() : mutileWin.show()
  mutileWin.isVisible() ? mutileWin.setSkipTaskbar(false):mutileWin.setSkipTaskbar(true);//
})
 

In the use Trayof the APIencountered problems

  • The difference between the file format of the icon macand the windowsfollowing, I finally found out through the official document query. Therefore, it is important to read the official documents carefully.
  • There is also Traythe question of destruction, which is ultimately the answer found on the Internet

Official posted at the end of this part of the text of Traythe document 's official website Tray relevant Api

Project packaging

  1. Use electron-packagerpackaging

    1.1 Install related packages

      npm install -D electron-packager
     

    1.2 Directly use command packaging, electron-packagerthe basic packaging commands are:

    electron-packager <location of project> <name of project> <platform> <architecture> <electron version> <optional options>
     

    Command description:

    • location of project: The path where the project is located
    • name of project: the name of the packaged project
    • platform: Determine which platform you want to build the application (Windows, Mac or Linux)
    • architecture: Determines whether to use x86 or x64 or both architectures
    • electron version: the version of electron
    • optional options: optional options

    1.3 Add under the pacage.jsonfilescript

     "electron:build": "electron-packager ./--all --asar --out=./release-builds --overwrite",
     

    Finally, you can use npmthis command to package

  2. Use electron-builderpackaging (I used this)

    1.1 Install related packages

      npm install -D electron-builder
     

    2.1 pacage.jsonAdd under the file

    "build": {
        "productName":"xxxx",//  exe 
        "appId": "com.xxx.xxxxx",//  
        "copyright":"xxxx",//   
        "files": [// 
          "package.json",
          "node_modules/**/*",
          "build/**/*",
          "config",
          "assets"
        ],
        "mac": {//mac 
          "target": [
            "dmg"
          ],
          "icon": "public/logo.png"
        },
        "win": { //windows 
            "icon": "public/icons/win_favicon.ico",
            "target": [
              {
                "target": "nsis"// 
              }
            ]
      }
     }
    
     

    Then scriptadd in the column

     "pack": "electron-builder --dir"
     

    Run it npm run packto be packaged

    After packaging, the file is very large. When I look for an online solution, I delete package.jsonthe dependenciesunnecessary dependencies, and then it feels too large after packaging 100MB. I wonder if there is a solution that can be reduced? Thank you very much.

summary

ElectronA cross-terminal desktop application development framework, I paid attention to it when it was released, and then I did not actually try it. Recently, the company has a demand, and then I have a great interest, so I just divided it by two. I started to work, and I consolidated it myself through this project reactbecause I used it reactfor development, and there was no choice vue. Because it is usually the project of my own company, vueI chose it react( vuethere is Electrona scaffolding specifically for writing electron-vue). In fact, I personally feel that using Electrondevelopment is to build the framework, and then the rest are some web pages, and some are in the web pages (the so-called communication between the rendering process and the main thread), so it is not a special operation of the system. The difficulty is not great.

However, through Electronthe development of desktop applications, I have a corresponding understanding of desktop applications. Then after thinking about it, the front end is really omnipotent. From web to mobile web, then cross-platform APP, cross-platform desktop application.

Then I would like to thank the Nuggets nickname Xu Jian Benzun juejin.im/post/684490... for the screenshot scheme released because I used it in this project, so I wrote the source. Thanks, the only shortcoming is that the dual-screen screenshot scheme has not been implemented. , And then I myself did not look for many methods, but I would be grateful for those who have ideas and thoughts. There seems to be various compilations on the Internet that call native modules. I haven't tried this solution yet. The first version was released first, and then the screenshot scheme was optimized.

Put a few Electronofficial document addresses:

Electron (official document): www.electronjs.org/

Electron's official quick start scaffolding: www.electronjs.org/docs/tutori...

Electron-Vue scaffolding: simulatedgreg.gitbooks.io/electron-vu...

Electron React Boilerplate: electron-react-boilerplate.js.org/

Electron's electron-builder package (official document): www.electron.build/

Finally put a few project pictures:

Windows:

Mac: