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

一芹橡、項(xiàng)目技術(shù)棧:Electron+react+react-router+antd

1韩玩、Electron:electron是一個(gè)使用js佑吝,html和css等的web技術(shù)創(chuàng)建原生桌面應(yīng)用的框架骨饿,他基于chromium和node.js围段,構(gòu)建的應(yīng)用可以在Mac顾翼,windows和Linux三個(gè)平臺(tái)上運(yùn)行。
2奈泪、React和react-router在該項(xiàng)目中負(fù)責(zé)構(gòu)建單頁(yè)面應(yīng)用和路由跳轉(zhuǎn)的實(shí)現(xiàn)适贸。
3灸芳、Antd作為UI框架。

二拜姿、項(xiàng)目搭建

1烙样、創(chuàng)建一個(gè)react項(xiàng)目

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

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

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

如果成功谒获,此時(shí)可以打開(kāi)瀏覽在http://localhost:3000/上會(huì)運(yùn)行著我們新建的項(xiàng)目。
可以通過(guò)npm run eject 彈出內(nèi)建晴埂,方便看出有哪些安裝的依賴究反。

2、引入electron

npm i electron --save-dev

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

3琅锻、配置

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

image.png

修改啟動(dòng)命令:


image.png

這里的dev想要同時(shí)執(zhí)行兩個(gè)命令,使用了|將兩個(gè)命令分開(kāi)恼蓬。
其中electron . --debug ,是調(diào)試命令需要運(yùn)行項(xiàng)目同時(shí)開(kāi)啟開(kāi)發(fā)者工具惊完,入口文件中會(huì)對(duì)這個(gè)命令進(jìn)行判斷,并開(kāi)啟指定工具处硬。

②main.js文件的編寫(xiě)

(復(fù)制github上electron的demo項(xiàng)目中的main.js做一些修改)
如下是當(dāng)前全部的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'));
    //接收渲染進(jìn)程的信息
    const ipc = require('electron').ipcMain;
    ipc.on('min', function () {
        mainWindow.minimize();
    });
    ipc.on('max', function () {
        mainWindow.maximize();
    });
    ipc.on("login",function () {
        mainWindow.maximize();
    });
    //如果是--debug 打開(kāi)開(kāi)發(fā)者工具小槐,窗口最大化,
    if (debug) {
        mainWindow.webContents.openDevTools();
        require('devtron').install();
    }

    mainWindow.on('closed', () => {
        mainWindow = null
    })
}
makeSingleInstance();
//app主進(jìn)程的事件和方法
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;

如上荷辕,注意將主進(jìn)程的loadUrl設(shè)置為localhost:3000凿跳,這樣可以展示運(yùn)行在這個(gè)地址下的頁(yè)面。

③安裝配置devtron插件

使用如下命令安裝:

npm i devtron --save-dev

安裝好后:在main.js中進(jìn)行配置疮方,參考上面main.js文件中的注釋控嗜。

四、進(jìn)程通信

項(xiàng)目構(gòu)建完成后骡显,這里開(kāi)始講解一下疆栏,react的項(xiàng)目和electron結(jié)合使用中的一個(gè)應(yīng)用問(wèn)題。先把需求提出來(lái)惫谤,如下圖壁顶,我們需要在頁(yè)面中點(diǎn)擊右上角最小化時(shí)將頁(yè)面窗口最小化(點(diǎn)擊×?xí)r的功能以此類(lèi)推),當(dāng)點(diǎn)擊登錄時(shí)修改窗口大小溜歪,并展示直播頁(yè)面博助。


直播器2.gif

要完成這個(gè)功能,要使用到Electron的API痹愚,這就要先從electron應(yīng)用結(jié)構(gòu)來(lái)說(shuō)起富岳,electron結(jié)構(gòu)中分為主進(jìn)程和渲染器進(jìn)程,如下是electron官網(wǎng)的一段話拯腮。

image.png

意思就是說(shuō)窖式,main.js就是主進(jìn)程,在主進(jìn)程中打開(kāi)的一個(gè)web頁(yè)面就是一個(gè)渲染進(jìn)程动壤,這個(gè)web頁(yè)面也就是該項(xiàng)目中的這個(gè)index.html铛绰,并且可以直接web頁(yè)面上通過(guò)nodejs的api進(jìn)行系統(tǒng)級(jí)的交互桶蛔。
如果我們沒(méi)有使用react,那么沒(méi)有什么問(wèn)題,但是在react引入electron就會(huì)報(bào)錯(cuò)了皆辽。所以,要在react中使用臣樱,就需要提前將electron賦值給window.electron 以方便使用训枢。在index.html的head中增加了一句js,如下圖:

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

此時(shí)醉旦,回想一下需求饶米,點(diǎn)擊“—”時(shí)最小化,我們發(fā)現(xiàn)觸發(fā)事件的ui在web頁(yè)面(react組件)中车胡,而想要操作的mainWindow對(duì)象(主進(jìn)程中打開(kāi)的那個(gè)頁(yè)面)卻在主進(jìn)程中檬输。所以,嘗試一個(gè)解決方案匈棘,讓web頁(yè)面(react組件)和主進(jìn)程進(jìn)行通信丧慈。
實(shí)現(xiàn)進(jìn)程通信使用到的api有ipcRenderer和ipcMain.

具體運(yùn)用如下:

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;

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

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

因此主卫,主進(jìn)程收到消息后逃默,即可對(duì)窗口進(jìn)行處理為最小化,而登錄功能與此類(lèi)似队秩,傳遞消息到主進(jìn)程同時(shí)跳轉(zhuǎn)頁(yè)面笑旺,主進(jìn)程收到消息后執(zhí)行窗口最大化,因此就實(shí)現(xiàn)了最初的需求馍资。
同理筒主,當(dāng)組件有其他操作需要主進(jìn)程作出反饋時(shí),也可以使用此方案鸟蟹。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乌妙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子建钥,更是在濱河造成了極大的恐慌藤韵,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熊经,死亡現(xiàn)場(chǎng)離奇詭異泽艘,居然都是意外死亡欲险,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)匹涮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)天试,“玉大人,你說(shuō)我怎么就攤上這事然低∠裁浚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵雳攘,是天一觀的道長(zhǎng)带兜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吨灭,這世上最難降的妖魔是什么刚照? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮沃于,結(jié)果婚禮上涩咖,老公的妹妹穿的比我還像新娘。我一直安慰自己繁莹,他們只是感情好檩互,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著咨演,像睡著了一般闸昨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上薄风,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天饵较,我揣著相機(jī)與錄音,去河邊找鬼遭赂。 笑死循诉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撇他。 我是一名探鬼主播茄猫,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼困肩!你這毒婦竟也來(lái)了划纽?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锌畸,失蹤者是張志新(化名)和其女友劉穎勇劣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體潭枣,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡比默,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年幻捏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片退敦。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粘咖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侈百,到底是詐尸還是另有隱情,我是刑警寧澤翰铡,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布钝域,位于F島的核電站,受9級(jí)特大地震影響锭魔,放射性物質(zhì)發(fā)生泄漏例证。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一迷捧、第九天 我趴在偏房一處隱蔽的房頂上張望织咧。 院中可真熱鬧,春花似錦漠秋、人聲如沸笙蒙。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捅位。三九已至,卻和暖如春搂抒,著一層夾襖步出監(jiān)牢的瞬間艇搀,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工求晶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留焰雕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓芳杏,卻偏偏與公主長(zhǎng)得像矩屁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蚜锨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容