Electron+React 快速搭建一個桌面應(yīng)用

一、項目技術(shù)棧:Electron+react+react-router+antd

1、Electron:electron是一個使用js,html和css等的web技術(shù)創(chuàng)建原生桌面應(yīng)用的框架,他基于chromium和node.js,構(gòu)建的應(yīng)用可以在Mac,windows和Linux三個平臺上運行。
2、React和react-router在該項目中負責構(gòu)建單頁面應(yīng)用和路由跳轉(zhuǎn)的實現(xiàn)。
3、Antd作為UI框架。

二、項目搭建

1、創(chuàng)建一個react項目

我們使用目前已經(jīng)比較成熟的create-react-app腳手架來創(chuàng)建一個react項目,關(guān)于這個腳手架的更多資料可以查看:https://facebook.github.io/create-react-app/docs/getting-started。

這里我們使用如下的命令:

npx create-react-app my-app 
cd my-app 
npm start

如果成功,此時可以打開瀏覽在http://localhost:3000/上會運行著我們新建的項目。
可以通過npm run eject 彈出內(nèi)建,方便看出有哪些安裝的依賴。

2、引入electron

npm i electron --save-dev

安裝成功后還不能直接運行一些命令,需要先進行一些配置,至少要有個electron需要用到的main.js入口文件(根目錄下)。

3、配置

①在package.json中配置入口文件,具體如下:

image.png

修改啟動命令:


image.png

這里的dev想要同時執(zhí)行兩個命令,使用了|將兩個命令分開。
其中electron . --debug ,是調(diào)試命令需要運行項目同時開啟開發(fā)者工具,入口文件中會對這個命令進行判斷,并開啟指定工具。

②main.js文件的編寫

(復(fù)制github上electron的demo項目中的main.js做一些修改)
如下是當前全部的main.js內(nèi)容

const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow = null;
//判斷命令行腳本的第二參數(shù)是否含--debug
const debug = /--debug/.test(process.argv[2]);
function makeSingleInstance () {
    if (process.mas) return;
    app.requestSingleInstanceLock();
    app.on('second-instance', () => {
        if (mainWindow) {
            if (mainWindow.isMinimized()) mainWindow.restore()
            mainWindow.focus()
        }
    })
}
function createWindow () {
    const windowOptions = {
        width: 400,
        height: 300,
        frame:false,
    };
    mainWindow = new BrowserWindow(windowOptions);
    mainWindow.loadURL("http://localhost:3000/");
    // mainWindow.loadURL(path.join('file://', __dirname, '/build/index.html'));
    //接收渲染進程的信息
    const ipc = require('electron').ipcMain;
    ipc.on('min', function () {
        mainWindow.minimize();
    });
    ipc.on('max', function () {
        mainWindow.maximize();
    });
    ipc.on("login",function () {
        mainWindow.maximize();
    });
    //如果是--debug 打開開發(fā)者工具,窗口最大化,
    if (debug) {
        mainWindow.webContents.openDevTools();
        require('devtron').install();
    }

    mainWindow.on('closed', () => {
        mainWindow = null
    })
}
makeSingleInstance();
//app主進程的事件和方法
app.on('ready', () => {
    createWindow();
});
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
});
app.on('activate', () => {
    if (mainWindow === null) {
        createWindow();
    }
});
module.exports = mainWindow;

如上,注意將主進程的loadUrl設(shè)置為localhost:3000,這樣可以展示運行在這個地址下的頁面。

③安裝配置devtron插件

使用如下命令安裝:

npm i devtron --save-dev

安裝好后:在main.js中進行配置,參考上面main.js文件中的注釋。

四、進程通信

項目構(gòu)建完成后,這里開始講解一下,react的項目和electron結(jié)合使用中的一個應(yīng)用問題。先把需求提出來,如下圖,我們需要在頁面中點擊右上角最小化時將頁面窗口最小化(點擊×?xí)r的功能以此類推),當點擊登錄時修改窗口大小,并展示直播頁面。


直播器2.gif

要完成這個功能,要使用到Electron的API,這就要先從electron應(yīng)用結(jié)構(gòu)來說起,electron結(jié)構(gòu)中分為主進程和渲染器進程,如下是electron官網(wǎng)的一段話。

image.png

意思就是說,main.js就是主進程,在主進程中打開的一個web頁面就是一個渲染進程,這個web頁面也就是該項目中的這個index.html,并且可以直接web頁面上通過nodejs的api進行系統(tǒng)級的交互。
如果我們沒有使用react,那么沒有什么問題,但是在react引入electron就會報錯了。所以,要在react中使用,就需要提前將electron賦值給window.electron 以方便使用。在index.html的head中增加了一句js,如下圖:

<script>global.electron = require('electron')</script>

此時,回想一下需求,點擊“—”時最小化,我們發(fā)現(xiàn)觸發(fā)事件的ui在web頁面(react組件)中,而想要操作的mainWindow對象(主進程中打開的那個頁面)卻在主進程中。所以,嘗試一個解決方案,讓web頁面(react組件)和主進程進行通信。
實現(xiàn)進程通信使用到的api有ipcRenderer和ipcMain.

具體運用如下:

import React from 'react';
import { Layout,Icon } from 'antd';
import "./UserLayout.scss";
import UserRouter from "../../router/userRouter";
const {ipcRenderer} = window.electron;
class UserLayout extends React.Component{
    closeWindow=()=>{
        window.close();
    };
    minWindow=()=>{
        ipcRenderer.send("min");
    };
    render(){
        return(
            <div className="login">
                <div className="top">
                    <div className="top-right">
                        <Icon type="minus" style={{margin:"0 8px"}} onClick={this.minWindow}/>
                        <Icon type="close" onClick={this.closeWindow}/>
                    </div>
                    <div className="top-center">
                        云直播
                    </div>
                </div>
                <div className="main">
                    <div className="main-content">
                        {UserRouter()}
                    </div>
                </div>
            </div>
        )
    }
}

export default UserLayout;

如上點擊時執(zhí)行minWindow,引入ipcRender發(fā)送一個消息”min”,main.js中有對應(yīng)的ipcMain進行監(jiān)聽,請看如下:

//接收渲染進程的信息
    const ipc = require('electron').ipcMain;
    ipc.on('min', function () {
        mainWindow.minimize();
    });

因此,主進程收到消息后,即可對窗口進行處理為最小化,而登錄功能與此類似,傳遞消息到主進程同時跳轉(zhuǎn)頁面,主進程收到消息后執(zhí)行窗口最大化,因此就實現(xiàn)了最初的需求。
同理,當組件有其他操作需要主進程作出反饋時,也可以使用此方案。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容