1. What is Electron?

Electron is a cross-platform desktop GUI application development framework based on Web front-end technology.

2. When to use Electron?

1. The company doesn’t have a dedicated desktop application developer, and Electron is a good choice for development when you need to take care of the front-end.

2. When an application needs to be developed for both the Web and desktop, Electron is a good place to develop.

3. Develop some efficiency tools, such as apI-class tools.

3. Advantages of Electron

  1. Open source core extensions are easy, currently based on node 6.x, and now that gyp is very human, it’s easy to be gay with c++ and js.

  2. Interface customization is strong, in principle as long as the Web can do he can do.

  3. Currently the cheapest cross-platform technology solution, HTML+JS has a large pool of front-end technical staff, and a large number of existing Web UI libraries. Most of them are good.

  4. It’s more stable and less buggy than other cross-platform solutions (QT GTK+, etc.). After all, once the browser shell is up and running, there aren’t too many problems in it.

  5. Convenient hot update. Download overlay done. Of course, this is an advantage that all scripts have in common.

4. Disadvantages of Electron

1. Stuck, slow startup, this may be webKit’s pot. After all, a browser does have a lot of functionality to support.

2. In addition to the main process, you may need to start some helper processes to complete the work. And every time you start a new process, the starting price is a NodeJS memory overhead.

3. Frame loss is the most serious, but I have been used to the silkiness of Native.

4. The bag is too big. (Obviously, even an empty package contains at least the volume of a browser.) Here’s how:

The entire package size is based on the size of Frameworks + Resources

The Frameworks electron core (size 174M, version 9.0.0) has little space to optimize

There is an electronic-Boilerplate package, which is a simplified electron, but it has not been updated for 3 years, and not many people use it

Resources app.asar is mainly the node_modules used by the main process and the packaged Resources of the project, so optimize app.asar mainly (also win).

5. What is the principle behind Electron building a cross-platform desktop application from a combination of HTML, CSS, and JavaScript?

Electron does this by merging Chromium and Node.js into the same runtime environment and packaging it as an application for Mac, Windows, and Linux.

6. Electron + Vue + TS scheme

For this scheme, we have a relatively mature library, Electron-vue. Note that electron requires a Python environment, if not installed in advance. Python official website: www.python.org/.

First, install vuE-CLI globally:

npm install -g vue-cli

Then, initialize:

vue init simulatedgreg/electron-vue vue-electron

Finally the Ann dependency runs:

CD vue-electron YARN # or NPM install YARN run dev # or NPM run dev

Operation effect:

Then, let’s analyze the directory structure:

You can see that there are two folders under the SRC folder, main and Renderer, which are the two processes in ELECTRON.

In the main process:

Index. js is the main process js

In the renderer process:

Assets: Places static resources, such as pictures, videos, and static configurations

Common: Places static JS, such as the public functions required by the page

Commponents: Place vUE pages

Router: Places the page route

Store: Places public modules, such as vuex

What to do when we want to call the ELECTRON API in a project:

The renderer sends data:

sendMsg(){
    this.$electron.ipcRenderer.send('toMain'.'I'm the data in the rendering process.')},Copy the code

The main process receives data:

var {ipcMain}=require('electron');
ipcMain.on('toMain'.(event,data) = >{  
    console.log(data);
});
Copy the code

How to use Node in a project:

var fs = require('fs');
export default {
    data() {
        return {
            msg: ' '}},methods: {
        runNode() {
            fs.readFile('package.json'.(err, data) = > {
                if (err) {
                    console.log(err);
                    return;
                }
                console.log(data.toString()); })}}}Copy the code

Then we add the TS configuration:

Create vue.sfc.d.ts global declaration file in SRC directory:

// configure ts to read.vue files
declare module "*.vue"{
  import Vue from 'vue'
  export default Vue
}
Copy the code

Install TS dependencies:

npm install typescript -d
npm install ts-loader -d
Copy the code

In webpack. Main. Config. Js and webpack renderer. Config. Js and TS configuration:

.module: {
    rules: [{test: /\.ts$/,
        use: {
        loader: "ts-loader".options: {
           appendTsSuffixTo: [/\.vue$/],}}},......resolve: {
    extensions: ['.ts'.'.js'.'.json'.'.node'],},...Copy the code

Add TS configuration, you need to change the original JS file to TS file. Then we must in webpack. The renderer. Config. Js configuration a thing: add a vue – property – in whiteListedModules decorator options:

//webpack.renderer.config.js
let whiteListedModules = ['vue'.'vue-property-decorator']
Copy the code

TSC –init generates tsconfig.json

"strict": false."experimentalDecorators":true.Copy the code

So, we’ve successfully introduced TS.

There are successful cases online for reference:

Tiny-evt: Vite2 + Vue3 + Electron12 + TypeScript git: github.com/neatfx/tiny…

Because it needs to integrate Vite, I made a comparison and chose evV scaffolding:

npm init evv
Copy the code

7. Electron + React + TS solution

Create react+ TS project:

npm install -g create-react-app
create-react-app electron-react --template typescript
cd electron-react
npm start
Copy the code

Install react-app-rewired, cross-env, and customize-cra NPM I -d react-app-rewired cross-customize-cra React-app-rewired2. x will need to install customize-cra to modify the webpack configuration. After installation, some configuration of scripts in package.json will need to be modified. React-app-rewired react-app-rewired react-app-rewired react-app-rewired react-app-rewired

/* package.json */
"scripts": {
   "start": "react-app-rewired start"."build": "react-app-rewired build"."test": "react-app-rewired test",}Copy the code

Babel-plugin-import: NPM install babel-plugin-import –save-dev

Install react-app-rewired, cross-env, and customize-cra: NPM I -d react-app-rewired cross-customize-cra

Create the react-app-rewired config file config-overrides. Js to extend the webpack configuration:

/* config-overrides.js */
const { override, fixBabelImports, } = require("customize-cra");

module.exports = override(
  fixBabelImports("import", {
    libraryName: "antd".libraryDirectory: "es".style: 'css',}));Copy the code

Install the ELECTRON environment and configure the entry file: NPM I-D electron

Put the main.js file under public.

/* main.js */
const { app, BrowserWindow } = require('electron');
const path = require('path');

let mainWindow = null;
const createWindow = () = > {
  let mainWindow = new BrowserWindow({
    width: 800.height: 600.webPreferences: {
      nodeIntegration: true,}});/** * loadURL is divided into two cases * 1. Development environment, pointing to the react development environment address * 2. In production, point to index.html */ after react build
  const startUrl =
    process.env.NODE_ENV === 'development'
      ? 'http://localhost:3000'
      :  path.join(__dirname, "/build/index.html");
  mainWindow.loadURL(startUrl);

  mainWindow.on('closed'.function () {
    mainWindow = null;
  });
};

app.on('ready', createWindow);

app.on('window-all-closed'.function () {
  if(process.platform ! = ='darwin') app.quit();
});

app.on('activate'.function () {
  if (mainWindow === null) createWindow();
});
Copy the code

Modify the package file:

/* package.json */
"main": "main.js"."author": "L"."description": "electron-react"."scripts": {
    "start": "cross-env BROWSER=none react-app-rewired start"."start-electron": "cross-env NODE_ENV=development electron ."."start-electron-prod": "electron ."
},
Copy the code

npm run start-electron

Run.

It is required to introduce Vite, so we need to replace WebPack with Vite. After consideration, I chose WP2vite.

npm install -g wp2vite
npm install
Copy the code

Wp2vite is a one-click tool for projects that use WebPack to develop and build with Vite (currently only vue and React are supported).

8. Packaging (electron – builder)

Electron – Vue has integrated the packaging tool, but there are still many problems, here I record:

  1. The dependency must be NPM or YARN, not CNPM.
  2. After downloading the dependency, download the auto-build dependency separately. CNPM and YARN cannot be downloaded.
  3. There are two pairs of tasks in build.js. Modify one pair of tasks.
  4. To manually configure the installation package, be sure to use this path: C:\Users\Administrator\AppData\Local\electron\Cache, put the installation package in this path, the installation package name is electron-v2.0.9-win32-x64.zip, I put it on gitlab.
  5. Manually download multispinner, NPM install multispinner -d, add in build.js

Const Multispinner = require(‘ Multispinner ‘).

Let’s configure the electron- React packing function. npm i -D electron-builder

Then configure some package-related parameters:

/* package.json */
  "homepage": ".".// Avoid the situation where resources such as CSS cannot be found
  "scripts": {
    "build-electron": "electron-builder"
  },
  "build": {
    // Package name
    "appId": "com.xxx.xxx".// Project name, which is also the generated installation file name
    "productName": "L".// Copyright information
    "copyright": "L © 2021".// The Application entry file "build/electron.js" does not exist
    "extends": null."directories": {
        // Output file path
      "output": "build-electron"
    },
    "files": [
      "./build/**/*"."./main.js"."./package.json"]."win": { // Win-related configuration
      "icon": "./favicon_256.ico"./* How to name the generated startup file */
      "artifactName": "${productName}.${ext}"
    },
    "nsis": {
       // Whether to install with one click and cannot change the directory. The default value is true
      "oneClick": false.// Whether to allow permission promotion. If false, the user must restart setup with the promoted permissions.
      "allowElevation": true.// Whether the installation path can be changed
      "allowToChangeInstallationDirectory": true.// Whether to create a desktop icon
      "createDesktopShortcut": true.// Create start menu icon
      "createStartMenuShortcut": true.// Install complete request run
      "runAfterFinish": true.// Install package icon
      "installerIcon": "./favicon_256.ico".// Uninstall program icon
      "uninstallerIcon": "./favicon_256.ico".// Install header icon
      "installerHeaderIcon": "./build/icons/aaa.ico".// Desktop icon name
      "shortcutName": "L"}},Copy the code

Create a new electron. Js file under public with the same contents as the main.js file

win.loadURL('http://localhost:3000/');
Copy the code

Modified to

win.loadURL(`file://${__dirname}/index.html`);
Copy the code

Then change the “main” item in package.json to “public/electron.js” and add the “build” item:

"build": {
  "appId": "com.example.electron-cra",
  "files": [
    "build/**/*",
    "node_modules/**/*"
  ],
  "directories":{
    "buildResources": "assets"
  },
  "extraMetadata":{
      "main":"build/electron.js"
    }
}
Copy the code

NPM run build-electron.

9. Comb the Electron module

Note: only summed up some common methods, specific can see: www.w3cschool.cn/electronman…

9.1 the shell

The shell module provides the association function to integrate other desktop clients.

An example of opening a URL in the user’s default browser:

var shell = require('shell');

shell.openExternal('https://github.com');
Copy the code
* * 9.1.1 shell. ShowItemInFolder (fullPath) * *

Open the folder where the file is located, which is usually selected as well.

9.1.2 shell. OpenItem (fullPath)

Open the file in default mode.

9.1.3 shell. OpenExternal (url)

Enable external protocols with system default Settings (for example,mailto: [email protected] opens the user’s default mail client).

9.1.4 shell. MoveItemToTrash (fullPath)

Deletes the specified path file and returns the status value for this operation (Boolean type).

9.1.5 shell. Beep ()

Play beep sounds (aka beeps).

9.2 screen

The Screen module retrieves screen size, display, mouse position and other information. The app module cannot be used until its ready event is triggered.

Note: in the renderer/developer toolbar, window.screen is a default DOM property, so writing var screen = require(‘electron’).screen will not work.

Example:

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

var mainWindow;

app.on('ready'.function() {
  var electronScreen = electron.screen;
  var size = electronScreen.getPrimaryDisplay().workAreaSize;
  mainWindow = new BrowserWindow({ width: size.width, height: size.height });
});
Copy the code
**Display object: **

The Display object represents a physical connection to the system. A fake Display may exist in a headless system, or a Display may be equivalent to a remote, virtual Display.

The Screen module triggers three kinds of events: Event: ‘display-added’

Returns:

Event Event newDisplay Object Emits an event when newDisplay is added

Event: ‘display-removed’

Returns:

Event Event oldDisplay Object Emits an event when oldDisplay is removed

Event: ‘display-metrics-changed’

Returns:

event Event display Object changedMetrics Array

9.2.1 screen. GetCursorScreenPoint ()

Returns the absolute path of the current mouse.

screen.getPrimaryDisplay()

Return the primary display.

screen.getAllDisplays()

Return a currently available display array.

9.2.2 screen. GetDisplayNearestPoint (point)

point Object x Integer y Integer

Returns the display closest to the specified point.

9.2.3 screen. GetDisplayMatching (the rect)

rect Object x Integer y Integer width Integer height Integer

Returns the display most closely related to the supplied boundary range.

9.3 the clipboard

The Clipboard module provides methods for copy and paste operations.

Example:

const clipboard = require('electron').clipboard;
clipboard.writeText('Example String');
Copy the code
* * 9.3.1 clipboard. ReadText ([type]) * *

Type String (Optional)

Returns content from clipBoard in plain text

9.3.2 clipboard. WriteText (text [type])

Text String Type String (Optional)

Add content to clipboard in plain text

9.3.3 clipboard. ReadHtml ([type])

Type String (Optional)

Returns the tag content in clipBoard

9.3.4 clipboard. WriteHtml (markup [type])

Markup String Type String (optional)

Add markup content to the Clipboard

9.3.5 clipboard. ReadImage ([type])

Type String (Optional)

Return the NativeImage content from the Clipboard

9.3.6 shall clipboard. WriteImage (image [type])

Image NativeImage Type String (Optional)

Writes an image to the Clipboard

9.3.7 clipboard. The clear ([type])

Type String (Optional)

Clear the clipBoard

9.4 crashReporter

The crash-Reporter module enables sending application crash reports.

Here is an example of automatically submitting a crash report to the server:

const crashReporter = require('electron').crashReporter;

crashReporter.start({
  productName: 'YourName'.companyName: 'YourCompany'.submitURL: 'https://your-domain.com/url-to-submit'.autoSubmit: true
});
Copy the code
* * 9.4.1 crashReporter. Start (options) * *

options:

companyName String

SubmitURL String – The path to send the crash report, in post mode.

ProductName String (Optional) – The default is Electron.

AutoSubmit Boolean – Whether to automatically submit. The default is true.

IgnoreSystemCrashHandler Boolean – Default is false.

Extra Object – An Object that you can define and send along with the crash report. Only string attributes can be sent correctly; nested objects are not supported.

Note: This method can only be used before using the other crashReporter APIs.

9.4.2 crashReporter. GetLastCrashReport ()

Returns the date and ID of the last crash report. Null is returned if no crash report has been sent or if crash report collection has not started.

9.4.3 crashReporter. GetUploadedReports ()

Returns a crash report for all uploads, each containing the upload date and ID.

9.5 nativeImage

In Electron, you can use file paths or nativeImage instances for all the apis that create images. If null is used, an empty image object is created.

When creating a tray or setup window icon, you can use the image path of a string:

var appIcon = new Tray('/Users/somebody/images/icon.png');
var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'});
Copy the code

Or read the image from the clipboard, which returns the nativeImage:

var image = clipboard.readImage();
var appIcon = new Tray(image);
Copy the code

Supported formats

Currently supports PNG and JPEG image formats. PNG is recommended because it supports transparency and lossless compression.

On Windows, you can also use the ICO icon format.

9.5.1 nativeImage. CreateEmpty ()

Create an empty instance of nativeImage.

9.5.2 nativeImage. CreateFromPath (path)

path String

Creates a new instance of nativeImage from the specified path.

9.5.3 nativeImage. CreateFromBuffer (buffer, scaleFactor [])

Buffer Buffer scaleFactor Double (optional)

Create a new instance of nativeImage from buffer. The default scaleFactor is 1.0.

9.5.4 nativeImage. CreateFromDataURL (dataURL)

dataURL String

Create a new instance of nativeImage from the dataURL.

9.6 ipcRenderer

The ipcRenderer module is an instance of the EventEmitter class. It provides a limited number of ways that you can send synchronous or asynchronous messages from the renderer process to the main process. You can also receive a response from the main process.

9.6.1 ipcRenderer. On (channel, the listener)

channel String listener Function

Listen for a channel and use listener(Event, args…) when a new message arrives. Call the listener.

9.6.2 ipcRenderer. Once (channel, the listener)

channel String listener Function

Add a one-time listener function for this event. This listener will be called the next time a new message is sent to a channel and then deleted.

9.6.3 ipcRenderer. RemoveListener (channel, the listener)

channel String listener Function

Removes the specified listener from the listener array in the specified channel.

9.6.4 ipcRenderer. RemoveAllListeners ([channel])

channel String (optional)

Deletes all listeners, or all listeners in a specified channel.

9.6.5 ipcRenderer. Send (channel [, arg1] [arg2], […]. )

Channel String ARG (optional)

Send an asynchronous message to the main process through a channel, or you can send arbitrary parameters. The parameters are serialized by JSON, and then there are no functions or prototype chains.

The main process processes messages by listening for channels using the ipcMain module.

Ipcrenderer. sendToHost(channel[, arg1][, arg2][,… )

Channel String ARG (optional)

Similar to ipcrenderer.send, but its events are sent to the element of the host page, not the main process.

9.7 desktopCapturer

The DesktopCapWomen module is used to get available resources, which are captured by getUserMedia.

// In the render process.
var desktopCapturer = require('electron').desktopCapturer;

desktopCapturer.getSources({types: ['window'.'screen']}, function(error, sources) {
  if (error) throw error;
  for (var i = 0; i < sources.length; ++i) {
    if (sources[i].name == "Electron") {
      navigator.webkitGetUserMedia({
        audio: false.video: {
          mandatory: {
            chromeMediaSource: 'desktop'.chromeMediaSourceId: sources[i].id,
            minWidth: 1280.maxWidth: 1280.minHeight: 720.maxHeight: 720
          }
        }
      }, gotStream, getUserMediaError);
      return; }}});function gotStream(stream) {
  document.querySelector('video').src = URL.createObjectURL(stream);
}

function getUserMediaError(e) {
  console.log('getUserMediaError');
}
Copy the code

When calling the navigator. WebkitGetUserMedia create a constraint object, if use desktopCapturer resources, must be set chromeMediaSource as the “desktop”, And audio is false.

If you capture audio and video of the entire desktop, you can set chromeMediaSource to “screen”, and audio to true. When using this method, you cannot specify a chromeMediaSourceId.

9.7.1 desktopCapturer. GetSources (options, callback)

Options Object types Array – A String Array, ThumbnailSize Object (optional) – Suggests the size of the thumbnail that can be scaled. Default is {width: 150, height: 150}. callback Function

Make a request for all desktop resources and call callback(error, sources) when the request is complete.

9.8 remote

The Remote module provides an easy way to conduct interprocess communication (IPC) between the renderer process (web page) and the host process.

In Electron, guI-related modules (dialog, Menu, etc.) only exist in the main process, not in the rendering process. In order to use them from the renderer, the IPC module is used to send interprocess messages to the main process. Using the Remote module, you can invoke methods on main process objects without explicitly sending interprocess messages, similar to Java’s RMI.

Here is an example of creating a browser window from the renderer process:

const remote = require('electron').remote;
const BrowserWindow = remote.BrowserWindow;

var win = new BrowserWindow({ width: 800.height: 600 });
win.loadURL('https://github.com');
Copy the code

Note: the reverse operation (from the main process access rendering process), can use webContents. ExecuteJavascript.

9.8.1 remote. The require (module)

module String

Returns the object returned by executing require(Module) in the main process.

9.8.2 remote. GetCurrentWindow ()

Returns the BrowserWindow object to which the page belongs.

9.8.3 remote. GetCurrentWebContents ()

Returns the WebContents object for the web page

9.8.4 remote. GetGlobal (name)

name String

Returns the global variable named name in the main process (that is, global[name]).

9.8.5 remote.process

Returns the Process object in the main process. Equivalent to remote.getGlobal(‘process’) but cached.

9.9 webFrame

The Web-frame module allows you to customize how to render the current web page.

Example: Enlarge current page to 200%.

var webFrame = require('electron').webFrame;

webFrame.setZoomFactor(2);
Copy the code

9.9.1 webFrame. SetZoomFactor (factor)

Factor Number – Scaling parameter.

Modifies the zoom parameter to the specified parameter value. The scaling parameter is a percent scale, so 300% = 3.0.

9.9.2 webFrame. GetZoomFactor ()

Returns the current scale parameter value.

9.9.3 webFrame. RegisterURLSchemeAsSecure (scheme)

scheme String

Register scheme as a secure scheme.

Safe Schemes do not raise mixed content warnings. For example, HTTPS and data are safe schemes that cannot be disabled by active network attacks.

9.9.4 webFrame. RegisterURLSchemeAsBypassingCSP (scheme)

scheme String

Ignore the security policy for the current web page content and load it directly from Scheme.

9.9.4 webFrame. ExecuteJavaScript (code [userGesture])

Code String userGesture Boolean (Optional) – Default: false.

Evaluate the page code.

In the browser window, some HTML APIs, such as requestFullScreen, can only be used with user gestures. Setting userGesture to true breaks this limitation

9.10 the app

The APP module is designed to control the entire application life cycle.

Example:

Exit the application when the last window is closed:

var app = require('app');
app.on('window-all-closed', function() {
  app.quit();
});
Copy the code

Event: ‘ready’

Triggered when Electron completes initialization.

Event: ‘window – all – closed’

Triggered when all Windows are closed.

This time can only be triggered if the application has not yet quit. If the user presses Cmd + Q or the developer calls app.quit(), Electron will attempt to close all Windows before firing the will-quit event, in which case window-all-closed will not be triggered.

Event: ‘before – quit’

Returns:

event Event

Triggered when the application starts to close its window. Calling event.preventDefault() will prevent the default behavior of terminating the application.

Event: ‘browser window – – focus’

Returns:

event Event

window BrowserWindow

Emitted when a BrowserWindow gets focus.

Event: ‘browser – Windows – created’

Returns:

event Event

window BrowserWindow

Emitted when a BrowserWindow is created.

9.10.1 app. The quit ()

Try to close all Windows. The before-quit event will be fired first. If all Windows are successfully closed, the Will-quit event will be fired and the application will be closed by default.

This method ensures that all beforeUnload and unload event handlers are executed correctly. If a window’s beforeUnload event handler returns false, the entire application may cancel the exit.

OS X 9.10.2 app. Hide ()

Hide all application Windows, not minimize them.

9.10.3 app. GetAppPath ()

Returns the file path of the current application.

9.10.4 APP.ClearRecentDocuments () OS X Windows

Clears the list of recently accessed documents.

9.10.5 app. IsAeroGlassEnabled () the Windows

This method returns true if DWM Composition (Aero Glass) is enabled, false otherwise. You can use this method to decide whether to enable transparent window effects, because if the user has not enabled DWM, transparent window effects are not effective.

9.11 BrowserWindow

BrowserWindow

Class gives you the power to create a browser window.

// In the main process.
const BrowserWindow = require('electron').BrowserWindow;

// Or in the renderer process.
const BrowserWindow = require('electron').remote.BrowserWindow;

var win = new BrowserWindow({ width: 800, height: 600, show: false });
win.on('closed', function() {
  win = null;
});

win.loadURL('https://github.com');
win.show();
Copy the code

You can also create Windows without using Chrome, using the Frameless Window API.

Event: ‘page-title-updated’

Returns:

event Event

Triggered when the document’s title changes, use event.preventDefault() to prevent the original window’s title from changing.

Event: ‘close’

Returns:

Event The event is emitted when the window is about to close. It fires before the beforeUnload and unload events of the DOM. To cancel this, use event.preventdefault ()

Normally you want to decide whether to close a window by using the beforeUnload handler, but it will also be triggered when the window reloads. In Electron, returning an empty string or false can cancel the closure.

Event: ‘unresponsive’

Trigger event when interface freezes.

Event: ‘minimize’

Triggered when the window is minimized.

Event: ‘scroll-touch-begin’ OS X

Triggered when the scrollbar event starts.

BrowserWindow.getAllWindows()

Returns an array of all objects with open Windows.

BrowserWindow.getFocusedWindow()

Returns the application’s current focus window, or NULL if it does not.

An instance object created with new BrowserWindow has the following properties:

// In this example `win` is our instance
var win = new BrowserWindow({ width: 800, height: 600 });
Copy the code

win.webContents

The WebContents object of this window, through which all interface related events and methods are done.

Check webContents Documentation for methods and events.

win.id

The unique ID of the window.

Instance methods

Instance objects created using new BrowserWindow have the following methods:

win.destroy()

Forcing a window close, unload and beforeunload does not fire, and close does not fire, but it guarantees closed firing.

win.close()

Try closing the window as if the user had clicked the close button. Although the page may cancel to close, check out the Close Event.

win.focus()

The window gets focus.

win.show()

Show and bring the window into focus.

win.hide()

Hide the window.

win.maximize()

Maximize the window.

win.minimize()

The window is minimized. On some OS, it will display in the Dock.

win.setBounds(options[, animate])

options Object

x Integer

y Integer

width Integer

height Integer

Animate Boolean (Optional) OS X

Resets the width and height of the window and moves it to the specified x and y positions.

win.getBounds()

Returns an object containing the width, height, x, and y coordinates of the window.

win.setSize(width, height[, animate])

width Integer

height Integer

Animate Boolean (Optional) OS X

Resets the width and height of the window.

win.setContentSize(width, height[, animate])

width Integer

height Integer

Animate Boolean (Optional) OS X

Resets the width and height of the window client (for example, the web interface).

win.center()

The window is centered.

9.12 webContents

WebContents is an event sender.

It renders and controls the web page and is an attribute of the BrowserWindow object. An example using webContents:

const BrowserWindow = require('electron').BrowserWindow;

var win = new BrowserWindow({width: 800, height: 1500});
win.loadURL("https://www.w3cschool.cn");

var webContents = win.webContents;
Copy the code

The webContents object can emit the following events:

Event: ‘did-finish-load’

The event is emitted when the navigation completes, and the onLoad event completes.

Event: ‘did-start-loading’

When TAB’s spinner starts spinning.

Event: ‘did-stop-loading’

When TAB’s spinner finishes spinning.

Event: ‘new-window’

Returns:

event Event

url String

frameName String

Disposition String – Can be default, foreground- TAB, background-tab, new-window and other.

Options Object – Arguments to use when creating a new BrowserWindow.

Raises an event when a page request opens the specified URL window. This can be through window.open or an external connection such as a request made.

A BrowserWindow specifying the URL is created by default.

The call event.preventDefault() can be used to prevent the window from opening.

Event: ‘will-navigate’ returns:

event Event

url String

Emits an event when the user or page wants to start navigation. It can happen when the window.location object changes or when the user clicks on a link in the page.

This event is not emitted when navigation is initiated programmatically using apis such as webcontents.loadURL and webcontents.back.

It also doesn’t happen within the page to jump, such as clicking on the anchor link or updating window.location.hash. The did-navigation-in-page event will do the trick.

Call event.preventDefault() to prevent navigation.

Event: ‘did-navigate’

Returns:

event Event

url String

Emits an event when a navigation ends.

This event is not emitted for in-page jumps, such as clicking an anchor link or updating window.location.hash. The did-navigation-in-page event will do the trick.

Event: ‘crashed’

Emits an event when the renderer crashes.

Event: ‘destroyed’

Emits an event when webContents is deleted

Event: ‘login’

Returns:

event Event

request Object

method String

url URL

referrer URL

authInfo Object

isProxy Boolean

scheme String

host String

port Integer

realm String

callback Function

Emits an event when webContents wants to do basic validation.

The usage method is similar to the Login Event of app.

Instance methods

The webContents object has the following instance methods:

9.12.1 webContents. LoadURL (url [options])

url URL

Options Object (Optional)

httpReferrer String – A HTTP Referrer url.

UserAgent String – the userAgent that generates the request

ExtraHeaders String – extraHeaders separated by “\n”

Load a url in a window that must contain a protocol prefix such as http:// or file://. If the load wants to ignore the HTTP cache, you can use the pragma header to do so.

const options = {"extraHeaders" : "pragma: no-cache\n"}
webContents.loadURL(url, options)
Copy the code

9.12.2 webContents. IsLoading ()

Returns a Boolean value that identifies whether the current page is being loaded.

9.12.3 webContents. IsLoading ()

Returns a Boolean value that identifies whether the current page is being loaded.

9.12.4 webContents. Reload ()

Reload the current page.

9.12.5 webContents. ReloadIgnoringCache ()

Reload the current page, ignoring the cache.

9.12.6 webContents. GoBack ()

Rewind the browser to the previous page.

9.12.7 webContents. GoForward ()

Tell the browser to go back to the next page.

9.12.8 webContents. GoToIndex (index)

index Integer

Causes the browser to return to the page of the specified index.

Instance attributes

The WebContents object also has the following properties:

webContents.session

Returns the session object used by this webContents.

webContents.hostWebContents

Returns the parent webContents of this webContents.

9.13 ipcMain

The ipcMain module is an instance of the EventEmitter class. When used in the main process, it controls asynchronous or synchronous messages sent by the renderer process (Web Page). A message sent from the renderer triggers the event.

Send a message

You can also send a message from the main process to the renderer to see more webcontents.send.

Sends a message with the event name channel.

In response to synchronous messages, you can set event. ReturnValue.

To respond to asynchronous messages, you can use event.sender.send(…). .

An example of sending and processing messages between the main and renderer processes:

// In main process.
const ipcMain = require('electron').ipcMain;
ipcMain.on('asynchronous-message', function(event, arg) {
  console.log(arg);  // prints "ping"
  event.sender.send('asynchronous-reply', 'pong');
});

ipcMain.on('synchronous-message', function(event, arg) {
  console.log(arg);  // prints "ping"
  event.returnValue = 'pong';
});
// In renderer process (web page).
const ipcRenderer = require('electron').ipcRenderer;
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"

ipcRenderer.on('asynchronous-reply', function(event, arg) {
  console.log(arg); // prints "pong"
});
ipcRenderer.send('asynchronous-message', 'ping');
Copy the code

Listen to the message

The ipcMain module has the following listening event methods:

9.13.1 ipcMain. On (channel, the listener)

channel String

listener Function

Listen on a channel. When a new message arrives, the listener(Event, args…) Call the listener.

9.13.2 ipcMain. Once (channel, the listener)

channel String

listener Function

Add a one-time listener function for the event. This listener is invoked only the next time a message arrives at a channel, after which it is deleted.

9.13.3 ipcMain. RemoveListener (channel, the listener)

channel String

listener Function

Removes a specific listener from the listener queue for a specific channel.

9.13.4 ipcMain. RemoveAllListeners ([channel])

Channel String (Optional)

Deletes all listeners, or all listeners for a specified channel.

The event object

The event object passed to callback has the following methods:

event.returnValue

Set this to the value returned in a synchronous message.

event.sender

Return the webContents that sent the message. You can call Event.sender. send to reply to the asynchronous message

9.14 the dialog

The Dialog module provides apis to display native system dialogs, such as open file boxes and alert boxes, so web applications can give users the same experience as system applications.

Example dialog box showing selecting files and directories:

var win = ... ; // BrowserWindow in which to show the dialog const dialog = require('electron').dialog; console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]}));Copy the code

Note on OS X: If you want to display dialogs like Sheets, just provide a reference object to browserWindow in the browserWindow argument.

9.14.1 dialog. ShowOpenDialog ([browserWindow,] options [, callback])

BrowserWindow browserWindow (optional)

options Object

title String

defaultPath String

filters Array

Properties Array – Contains the feature values for the dialog box. The options are openFile, openDirectory, multiSelections and createDirectory

Callback Function (Optional)

This method returns an array of file paths that the user can choose on success, and undefined on failure.

Filters Specifies an array of files for the user to display or select when it needs to restrict the user’s behavior. Such as:

{
  filters: [
    { name: 'Images', extensions: ['jpg', 'png', 'gif'] },
    { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] },
    { name: 'Custom File Type', extensions: ['as'] },
    { name: 'All Files', extensions: ['*'] }
  ]
}
Copy the code

The Extensions array should contain only the extension and should not contain wildcards or ‘.’ numbers (e.g.’ PNG ‘is correct, but ‘.png’ and ‘.png’ are not). To display all files, use the ” wildcard (other wildcards are not supported).

If callback is called, the API is called asynchronously, and the result is displayed using callback(Filenames).

Note: On Windows and Linux, An open Dialog cannot be both a file selection box and a directory selection box, so setting properties to [‘openFile’, ‘openDirectory’] on these platforms will display a directory selection box.

9.14.2 dialog. ShowErrorBox (title, content)

Displays a traditional error message dialog box.

This API can be safely called before the APP module fires the ready event, and is usually used to report errors in the early stages of startup. On Linux, if called before the APP module triggers the ready event, Message will be triggered to display the STderr (output file) without the actual GUI box.

9.15 the menu

The Menu class can be used to create native menus, which can be used as application menus and context menus.

This module is a module of the main process and can be called by the remote module to the renderer.

Each menu has one or more menu items, and each menu item can have submenus.

The following is an example of a menu dynamically created in a web page (renderer) using the remote module and displayed by right-clicking:

<!-- index.html -->
<script>
const remote = require('electron').remote;
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;

var menu = new Menu();
menu.append(new MenuItem({ label: 'MenuItem1', click: function() { console.log('item 1 clicked'); } }));
menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }));

window.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  menu.popup(remote.getCurrentWindow());
}, false);
</script>
Copy the code

9.15.1 Menu. SetApplicationMenu (Menu)

menu Menu

On OS X, set application menu. On Windows and Linux, set menu at the top of each window.

9.15.2 Menu. SendActionToFirstResponder OS X (action)

action String

Sends the action to the first responder of the application. This is used to mimic the default behavior of Cocoa menus. Usually you only need to use the MenuItem attribute role.

9.15.3 Menu. BuildFromTemplate (template)

template Array

Normally, template is just an array parameter used to create a MenuItem.

You can also add other things to the template element, and they become properties of existing menu items.

Instance methods

The menu object has the following instance methods:

menu.popup([browserWindow, x, y, positioningItem])

BrowserWindow browserWindow (Optional) – Null by default.

X Number (Optional) – The default value is -1.

Y Number (must be if x is set) – Default is -1.

PositioningItem Number (Optional) OS X – Index of the menu item below the mouse position at the specified coordinates. Default is -1. The Context Menu is displayed in browserWindow. You can optionally provide specified X, y to set where the menu should be placed, otherwise it will default to the current mouse position.

menu.append(menuItem)

menuItem MenuItem

Add menu items.

menu.insert(pos, menuItem)

pos Integer

menuItem MenuItem

Adds a menu item at the specified location.

menu.items()

Gets an array of menu items.

9.16 protocol

The Protocol module can register a custom protocol or use an existing protocol.

For example, using a protocol similar to the file:// feature:

const electron = require('electron');
const app = electron.app;
const path = require('path');

app.on('ready', function() {
    var protocol = electron.protocol;
    protocol.registerFileProtocol('atom', function(request, callback) {
      var url = request.url.substr(7);
      callback({path: path.normalize(__dirname + '/' + url)});
    }, function (error) {
      if (error)
        console.error('Failed to register protocol')
    });
});
Copy the code

Note: This module is only available after the app module’s ready event is triggered.

9.16.1 protocol. RegisterStandardSchemes (schemes)

Schemes Array – Registers a custom schema as a standard schema.

A standard scheme follows the Generic URI Syntax standard of RFC 3986. This includes file: and filesystem:.

9.16.2 protocol. RegisterServiceWorkerSchemes (schemes)

Schemes Array – Registers a custom schema to handle service workers.

9.16.3 protocol. UnregisterProtocol (scheme [, completion])

scheme String

Completion Function (Optional)

Deregister the user-defined protocol scheme.

9.17 the session

The session module can be used to create a new session object.

You can also use a session on an existing page by using the session property of webContents, which is the property of BrowserWindow.

const BrowserWindow = require('electron').BrowserWindow;

var win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL("http://github.com");

var ses = win.webContents.session;
Copy the code

Examples of event

Instance Session has the following events:

Event: ‘will-download’

event Event

item DownloadItem

webContents WebContents

Triggered when Electron is about to download an item from webContents.

Call event.preventDefault() to cancel the download and prevent this item from being available in the process’s next tick.

session.defaultSession.on('will-download', function(event, item, webContents) {
  event.preventDefault();
  require('request')(item.getURL(), function(data) {
    require('fs').writeFileSync('/somewhere', data);
  });
});
Copy the code

Instance methods

9.17.1 ses. Cookies

Cookies give you the power to query and modify cookies. For example:

/ / query all the cookies, session. The defaultSession. Cookies, get ({}, function (error, cookies) {the console. The log (cookies); }); / / queries related to the specified url all cookies, session. The defaultSession. Cookies, get ({url: "http://www.github.com" }, function(error, cookies) { console.log(cookies); }); / / setting cookies; // may overwrite equivalent cookies if they exist. var cookie = { url : "http://www.github.com", name : "dummy_name", value : "dummy" }; session.defaultSession.cookies.set(cookie, function(error) { if (error) console.error(error); });Copy the code

9.17.2 ses. Cookies. Get (filter, the callback)

filter Object

Url String (Optional) – The URL associated with obtaining cookies. Otherwise, cookies are retrieved from all urls.

Name String (Optional) – Filter cookies by name.

Domain String (Optional) – Obtain cookies of the domain name or subdomain name.

Path String (Optional) – Obtains cookies of the corresponding path.

Secure Boolean (Optional) – Filter cookies by security.

Session Boolean (Optional) – Filter session or persistent cookies.

callback Function

Send a request to get cookies for all matching details, and when done, callback(error, cookies) is called.

A cookie is a cookie object.

cookie Object

Name String – Cookie name.

Value String – Cookie value.

Domain string-cookie domain name.

HostOnly String – Indicates whether cookie is a host-only cookie.

Path String – Cookie path.

Secure Boolean – Whether it is a secure cookie.

HttpOnly Boolean – Whether it is only an HTTP cookie.

Session Boolean – Cookie specifies whether a session cookie or a persistent cookie with an expiration date.

ExpirationDate Double (optional)- expirationDate of a cookie. The value is the number of seconds since the UNIX era. Session cookies are not provided.

9.17.3 ses. Cookies. Set (the details, the callback)

details Object

Url String – The URL associated with obtaining cookies.

Name String – Cookie name. Ignore the default is null.

Value String – Cookie value. Ignore the default is null.

Domain String – Indicates the domain name of cookie. Ignore the default is null.

Path String – Path of the cookie. Ignore the default is null.

Secure Boolean – Whether security identification has been performed. The default is false.

Session Boolean – Indicates whether the HttpOnly identity is present. The default is false.

ExpirationDate double-cookie expirationDate. The value is the number of seconds since the UNIX era. If ignored, the cookie becomes a session cookie.

Callback Function Sets the cookie using details, and drops a callback(error) when done.

9.17.4 ses. Cookies. Remove (url, name, the callback)

Url String – Url associated with cookies.

Name String – Name of the cookie to be deleted.

callback Function

Delete the cookie that matches the URL and name, and call callback with callback() when done.

9.17.5 ses. GetCacheSize (the callback)

callback Function

Size Integer – Specifies the size of the cache in bytes.

Returns the current cache size of the session.

9.17.6 ses. ClearCache (the callback)

Callback Function – called when the operation is complete

Clear the HTTP cache of the session.

9.18 Tray

Tray is used to represent an icon that is in the notification area of the running system and is usually added to a Context menu.

const electron = require('electron');
const app = electron.app;
const Menu = electron.Menu;
const Tray = electron.Tray;

var appIcon = null;
app.on('ready', function(){
  appIcon = new Tray('/path/to/my/icon');
  var contextMenu = Menu.buildFromTemplate([
    { label: 'Item1', type: 'radio' },
    { label: 'Item2', type: 'radio' },
    { label: 'Item3', type: 'radio', checked: true },
    { label: 'Item4', type: 'radio' }
  ]);
  appIcon.setToolTip('This is my application.');
  appIcon.setContextMenu(contextMenu);
});
Copy the code

Platform limitations:

On Linux, use application indicators if they are supported, and GtkStatusIcon instead.

On Linux, configured only with application indicator support, you must install LibAppindicator1 for Tray Icon to execute.

The application indicator is displayed only if it has context Menu.

Click events are ignored when application indicators are used on Linux.

On Linux, setContextMenu needs to be called again for the individual MenuItem to take effect. Such as:

contextMenu.items[2].checked = false;
appIcon.setContextMenu(contextMenu);
Copy the code

If you want to maintain exactly the same behavior across all platforms, you should not rely on click events, but always add a Context Menu to the Tray Icon.

9.18.1 Tray. Destroy ()

Delete the Tray Icon immediately.

9.18.2 Tray. SetImage (image)

image NativeImage

Associate the Image with the Tray Icon.

OS X 9.18.3 Tray. SetPressedImage (image)

image NativeImage

Associate image with Tray Icon when pressing tray Icon on OS X.

9.18.4 Tray. SetToolTip (toolTip)

toolTip String

Set hover Text for tray Icon.

OS X 9.18.5 Tray. SetTitle (title)

title String

Set the title along the Tray Icon in the status bar.

OS X 9.18.6 Tray. SetHighlightMode (highlight)

highlight Boolean

Set the background color of tray Icon to highlight blue when it is clicked. The default is true.

9.18.7 Tray. SetContextMenu (menu)

menu Menu

Set context Menu for this icon.

9.19 global – shortcut

The Global-Shortcut module allows you to easily set (register/unregister) shortcut keys for various custom operations.

Do not use this module before the app Module responds to the ready message.

var app = require('app'); var globalShortcut = require('electron').globalShortcut; app.on('ready', function() { // Register a 'ctrl+x' shortcut listener. var ret = globalShortcut.register('ctrl+x', function() { console.log('ctrl+x is pressed'); }) if (! ret) { console.log('registration failed'); } // Check whether a shortcut is registered. console.log(globalShortcut.isRegistered('ctrl+x')); }); app.on('will-quit', function() { // Unregister a shortcut. globalShortcut.unregister('ctrl+x'); // Unregister all shortcuts. globalShortcut.unregisterAll(); });Copy the code

9.19.1 globalShortcut. Register (accelerator, the callback)

accelerator Accelerator

callback Function

Register the Accelerator shortcut. The callback function is called when the user presses the registered shortcut key.

9.19.2 globalShortcut. IsRegistered (accelerator)

accelerator Accelerator

Querying whether the Accelerator shortcut is already registered will return true(registered) or false(unregistered).

9.19.3 globalShortcut. Unregister (accelerator)

accelerator Accelerator

Deactivate the global shortcut accelerator.

9.19.4 globalShortcut. UnregisterAll ()

Unregister all global shortcuts registered for the application.

9.20 contentTracing

The Content-Tracing module is used to collect search data generated by the underlying Chromium Content module. This module does not have a Web interface, so we need to add Chrome ://tracing/ to the Chrome browser to load the generated file and view the results.

const contentTracing = require('electron').contentTracing;

const options = {
  categoryFilter: '*',
  traceOptions: 'record-until-full,enable-sampling'
}

contentTracing.startRecording(options, function() {
  console.log('Tracing started');

  setTimeout(function() {
    contentTracing.stopRecording('', function(path) {
      console.log('Tracing data recorded to ' + path);
    });
  }, 5000);
});
Copy the code

9.20.1 contentTracing. From getCategories was an (the callback)

callback Function

Get a set of classification groups. Classification groups can be changed to new code paths.

Once all child processes have received the getCategories method request, the categories group calls callback.

9.20.2 contentTracing. StartRecording (options, callback)

options Object

categoryFilter String

traceOptions String

callback Function

Start recording all processes.

As soon as a request is received to start recording, the recording is started immediately and the child process is heard asynchronously. Callback will be called when all child processes have received the startRecording request.

CategoryFilter is a filter that controls which category groups should be used for lookup. Filters should have an optional – prefix to exclude matching classification groups. The same list is not allowed to be both included and excluded.

9.20.3 contentTracing. StopRecording (resultFilePath, callback)

resultFilePath String

callback Function

Stops recording of all child processes.

Child processes typically cache lookup data and simply intercept and send the data to the main process. This helps reduce the running overhead of the lookup before sending the lookup data through IPC, which is valuable. Therefore, to send the lookup data, we should asynchronously notify all child processes to intercept any lookup data.

Once all child processes have received a stopRecording request, callback is called and a file containing the lookup data is returned.

If resultFilePath is not empty, the lookup data is written to it, otherwise a temporary file is written. If the actual file path is not empty, callback is called.

9.21 powerSaveBlocker

The powerSaveBlocker module is used to prevent the application from going into sleep mode, so this allows the application to keep the system and screen working.

const powerSaveBlocker = require('electron').powerSaveBlocker;

var id = powerSaveBlocker.start('prevent-display-sleep');
console.log(powerSaveBlocker.isStarted(id));

powerSaveBlocker.stop(id);
Copy the code

9.21.1 powerSaveBlocker. Start (type)

Type String – Forcibly saves the blocking type.

Prevent-app-suspension – Prevents the application from being suspended. Keep the system active, but allow the screen to remain dark. Use case: Download files or play audio.

Prevent-display-sleep – Prevents the application from sleeping. Keep the system and screen active and the screen always lit. Use case: Play audio.

Start blocking the system from going into sleep mode. Returns an integer that identifies the blocker that remains active.

Note: Prevent-display-sleep has a higher precedence of prevent-app-suspension. Only the highest priority takes effect. In other words, prevent-display-sleep always has a higher priority than Prevent-app-suspension.

For example, prevent-app-suspension is called in request A, and prevent-display-sleep is called in request B. Prevent-display-sleep will work until B stops calling. After that, Prevent-app-suspension came into effect.

9.21.2 powerSaveBlocker. Stop (id)

Id Integer – The active Blocker ID returned by powerSaveBlocker.start. Deactivate the specified Blocker.

9.21.3 powerSaveBlocker. IsStarted (id)

Id Integer – The active Blocker ID returned by powerSaveBlocker.start. Returns Boolean if the corresponding powerSaveBlocker has been started.

9.22 powerMonitor

The power-monitor module is used to monitor changes in the energy region. Can only be used in the main process. The app module cannot be used after the ready event is triggered.

app.on('ready', function() {
  require('electron').powerMonitor.on('suspend', function() {
    console.log('The system is going to sleep');
  });
});
Copy the code

The power-Monitor module can fire the following events:

Event: ‘suspend’

Triggered when the system is suspended.

Event: ‘resume’

Triggered when the system resumes working. Emitted when system is resuming.

Event: ‘on-ac’

Triggered when the system is using ac. Emitted when the system changes to AC power.

Event: ‘on-battery’

Triggered when the system is running on battery power. Emitted when system changes to battery power.

9.23 autoUpdater

This module provides an interface to the Squirrel automatic update framework.

9.23.1 autoUpdater. SetFeedURL (url)

url String

Set up the URL to check for updates and initiate automatic updates. This URL cannot be changed once set.

9.23.2 autoUpdater. CheckForUpdates ()

Check with the server to see if any updates are available now. Before calling this method, you must first call setFeedURL.

9.23.3 autoUpdater. QuitAndInstall ()

After downloading, restart the current application and install the update. This method should be called only after the update-Downloaded event is triggered.

10. Frame selection

Through VUE3 + TS + Electron16 + vite2 and React + TS + Electron16 + vite2, we have a concrete understanding of the two routes. Therefore, we need to make a choice about which framework to choose and the subsequent infrastructure construction.

First let’s take a look at the Vue package:

React package

Then consider the suitability of Vue and React to VITe2 and TS… I didn’t really think of anything, but I came to the conclusion that everything would work.

In terms of frame selection, I have considered many aspects, such as package size, adaptability to TS and Vite, difficulty in getting started, and ecology. I did not find any reason to convince myself to choose a certain frame. I have studied the electron project of other companies and found that they all choose Vue. In addition, the library about electron + vue on the Internet is more complete than React, and the debug information is more than React.

After considering the business environment, we needed to do multi-person video and shared whiteboard, so we had higher requirements on data update. Moreover, Vue’s DOM rendering and data processing were stronger than React, so we finally chose Vue.

11. Component library selection

Here I consider two choices, one is Elemenmt-Plus and the other is Ant-design-Vue.

Element-plus is a Vue 3-based desktop component library for developers, designers, and product managers. It’s very targeted, and both vuE3 and the desktop are very responsive to our needs.

Antd-vue is an adaptation of ANTD to VUE. I have used it before, and I feel ok.

Finally, I chose Element-Plus, which is more targeted.

npm i element-plus --save
Copy the code

And then you can just import it all.

import { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

createApp(App)
  .use(ElementPlus)
  .mount("#app");
Copy the code

12. Follow-up planning (infrastructure and performance optimization)

The project is still in the start-up stage, and many of my plans are difficult to be implemented at present, such as:

  1. Configure ESLint + prettier + Yorkie (husky)
  2. Online alarm system sentry.js
  3. Configure burying points and permission management
  4. Front and Back End Interaction Scheme (Swagger /Yapi)
  5. Automatic publishing (Jenkins)
  6. Memory walk check and performance optimization

If possible, infrastructure steps and performance parameter analysis, as well as performance optimization and specific data will be sent out.