It’s sunny. Electron is leaving today

Time:2020-4-5

It’s sunny. Electron is leaving today

It takes a little time to read this article. If the time is short, you can read the beginning and the end summary. Thanks
Come and have fun


Let me ask you a question first

  1. What is electron
  2. What’s electron for? What’s the solution
  3. How about writing a todo?
  4. How to implement desktop program, conceptual meaning, and underlying technology?

How to install the first step

First of all, our choice can be based on the development dependency of save
npm install electron --save-dev
You can also install electron globally
npm install electron -g

Here’s a piece of translation

Electron lets you use pure JavaScript to call rich native APIs to create desktop applications. You can think of it as a variation of node. JS, which focuses on desktop applications, rather than a web server.

This does not mean that electron is JavaScript bound to the (GUI) library. Instead, electron uses web pages as its GUI, so you can think of it as a simplified version of chromium browser controlled by JavaScript.

awesome

Step 2 understand the basic concepts

Electron is divided into main process and rendering process

The main script that the main process runs package.json is called the main process. Scripts running in the main process display a GUI as web pages are created.
It reminds me. The feeling of GUI main thread when doing Python and Java before… )

Electron’s web pages run in a process that becomes a rendering process. And get some low-level interaction between the page and the operating system

Main process rendering process difference

Main process uses browserwindow instance to create page

Each browserwindow instance runs the page in its own rendering process.

When a browserwindow instance is destroyed, the corresponding rendering process will also be terminated.

The rendering process is independent of each other and managed by the main process.

The rendering process only needs to care about their own pages.

GUI operation is not allowed in web pages.

Communication between the corresponding rendering process and the main process is required.

Communication method

1. Use HTML5 APIs such as storage API, localstorage, sessionstorage, or indexeddb

2. IPC communication (ipcrenderer and ipcmain)

3. RPC communication (remote module)

Here’s how to implement a todolist

Start coding first.

It controls files similar to package.json.

The main thread is created by the entry file defined by main

Here is the incomplete code. Probable.

You need the full code to see the GitHub address.

todolist

The project directory is about
todo
-- addWindow.html
-- main.js
-- package.json
-- window.html

The entry file is our main.js, which is the central scheduling in an application.

//Modules can be introduced just like when using nodejs
//This is the so-called main process. It looks like a nodejs script
const electron = require('electron');
const url = require('url');
const path = require('path');


const {app,BrowserWindow,Menu,ipcMain} = electron;

//Setting up the environment
process.env.NODE_ENV = 'production';

let mainWindow;
let addWindow;
//listen for app to be ready

app.on('ready',function(){
    //1. Create a new window
    mainWindow = new BrowserWindow({});
    //Load HTML into window
    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname,'window.html'),
        Protocol: 'file:', // protocol
        slashes:true
    }));
    //file:/dirname/mainWindow.html

    //6. Close the large window close the whole program
    mainWindow.on('close',function(){
        app.quit();
    })

    //2. Setup menu
    const mainMenu = Menu.buildFromTemplate(mainMenuTemplate);
    Menu.setApplicationMenu(mainMenu);

})


//handle create add window 

function createAddWindow(){
    //5. New window
    addWindow = new BrowserWindow({
        width: 300,
        height: 200,
        title: 'Add TODO list item'
    });
    //load html into window
    addWindow.loadURL(url.format({
        pathname: path.join(__dirname,'addWindow.html'),
        Protocol: 'file:', // protocol
        slashes:true
    }));
    //Garbage collection
    addWindow.on('close',function(){
        addWindow = null;
    })
}

//7. Capture sub window IPC item: add
// IPC communication
ipcMain.on('item:add',function(e,item){
    console.log('item');
    mainWindow.webContents.send('item:add',item);
    addWindow.close();
});

const mainMenuTemplate = [{
    label: 'File',
    Submenu: [// 3. Set submenu
        {
            label: 'Add Item',
            click(){
                //4. New window
                createAddWindow();
            }

        },
        {
            label: 'Clear Items',
            click(){
                mainWindow.webContents.send('item:clear');
            }
        },
        {
            label: 'Quit',
            Accelerator: process. Platform = = 'Darwin'? 'common + Q': 'Ctrl + Q', // shortcut key for OS version differentiation
            click(){
                app.quit();
            }
        }
    ]
}];


// if mac , add empty object to menu
if(process.platform =='darwin'){
    mainMenuTemplate.unshift({});
}


//Differentiate development environment
if(process.env.NODE_ENV !== 'production'){
    // add devtools
    mainMenuTemplate.push({
        label:'Developer tools',
        submenu:[
            {
                role:'reload'
            },
            {
                label: 'Toggle DevTools',
                Accelerator: process. Platform = = 'Darwin'? 'common + I': 'Ctrl + I', // shortcut key for OS version differentiation,
                click(item,focusedWindow){
                    //Differentiate click window
                    focusedWindow.toggleDevTools();
                }
            }
        ]
    });
}

The main process is set with IPC communication port.
Monitor render process events

addWindow.html

<div class="container">
            <form>
                    <div>
                        <label>
                            Enter Item
                        </label>
                        <input type="text" id="item" autofocus>
                    </div>
                    <button class="btn waves-effect waves-light" type="submit">add Item</button>
                    <! -- send item to MainWindow -- >
                </form>
    </div>
    
    
        const electron = require('electron');
        const {ipcRenderer} = electron;
        
        const form = document.querySelector('form');
        form.addEventListener('submit',function(e){
            e.preventDefault();
            // console.log(123);
            const item = document.querySelector('#item');
            ipcRenderer.send('item:add',item.value);
            //Using IPC for communication
            
        })

Main process render page

   <nav>
        <div class="nav-wrapper">
            <a class="brand-logo center">
                TODO LIST
            </a>
        </div>
    </nav>
    <ul id="mainContainer">

    </ul>


    <script>
        const electron = require('electron');
        const {ipcRenderer} = electron;
        const ul = document.querySelector('#mainContainer');
        ipcRenderer.on('item:add',function(e,item){
            ul.className = 'collection';
            const li = document.createElement('li');
            li.className = 'collection-item';
            const itemText = document.createTextNode(item);
            li.appendChild(itemText);
            // const li = '<li class="collection-item">'+item+'</li>';
            ul.appendChild(li);  
            // ul.innerHTML = ul.innerHTML+li;     
        })
        //clear items
        ipcRenderer.on('item:clear',function(e){
            ul.innerHTML = '';
            // if(ul.clildren.length == 0){
                ul.className = '';
            // }
        })
        // Remove item by doubleclick
        ul.addEventListener('dblclick',function(e){
            e.target.remove();
            // console.log(ul.clildren.length);
            if(ul.children.length == 0){
                ul.className = '';
            }
        })
    </script>

Demo summary

Probably.understand

  • Node module can be used
  • Rendering interface can use web page rendering
  • Understanding interprocess communication

debugging

Debugging of rendering process

The debugging of rendering can be opened through the opendevtool API of webcontent to debug web pages

const { BrowserWindow } = require('electron')
  
let win = new BrowserWindow()
win.webContents.openDevTools()

Main process debugging

command line switch
--inspect=[port]
Listen to the debugger protocol information about port in V8 engine

--inspect-brk=[port]
It's the same as the -- inspector, but it pauses on the first line of the JavaScript script.
external debugger
  • Connect to chrome by visiting chrome: / / inspect and select the electron application to check there.
  • Using vscode to debug the main process

(I feel like the traditional debug nodejs in browser)


chromium

Because of the combination of chrome, we can also use the new features of HTML5 in our rendering process
For example, offline notification, offline caching, etc.


summary

  • Electron is a library that can build desktop applications with JavaScript, HTML, and CSS
  • Multi terminal compatibility (a set of codes)
  • Chromium, node.js, API calling local functions of operating system
  • Seamless use of node

Some links

  • Todo example code
  • Electronic GitHub address
  • Electronic Chinese document

I can be found in these places

  • http://zwk.life
  • Gmail email: a2fuzzk1njmwqgdtywlslmnvbq==
  • QQ email: ota3nzq3odc0qhfxlmnvbq==
  • github ZWkang

Digression

This article was written earlier, and we hope to understand some defects (2017)

If you have any doubts, please discuss.