美文网首页react
Electron+React 快速搭建一个桌面应用

Electron+React 快速搭建一个桌面应用

作者: 变态的小水瓶 | 来源:发表于2019-03-18 18:11 被阅读0次

    一、项目技术栈:Electron+react+react-router+antd

    1、Electron:electron是一个使用js,html和css等的web技术创建原生桌面应用的框架,他基于chromium和node.js,构建的应用可以在Mac,windows和Linux三个平台上运行。
    2、React和react-router在该项目中负责构建单页面应用和路由跳转的实现。
    3、Antd作为UI框架。

    二、项目搭建

    1、创建一个react项目

    我们使用目前已经比较成熟的create-react-app脚手架来创建一个react项目,关于这个脚手架的更多资料可以查看: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 弹出内建,方便看出有哪些安装的依赖。

    2、引入electron

    npm i electron --save-dev
    

    安装成功后还不能直接运行一些命令,需要先进行一些配置,至少要有个electron需要用到的main.js入口文件(根目录下)。

    3、配置

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

    image.png

    修改启动命令:


    image.png

    这里的dev想要同时执行两个命令,使用了|将两个命令分开。
    其中electron . --debug ,是调试命令需要运行项目同时开启开发者工具,入口文件中会对这个命令进行判断,并开启指定工具。

    ②main.js文件的编写

    (复制github上electron的demo项目中的main.js做一些修改)
    如下是当前全部的main.js内容

    const { app, BrowserWindow } = require('electron');
    const path = require('path');
    let mainWindow = null;
    //判断命令行脚本的第二参数是否含--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 打开开发者工具,窗口最大化,
        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设置为localhost:3000,这样可以展示运行在这个地址下的页面。

    ③安装配置devtron插件

    使用如下命令安装:

    npm i devtron --save-dev
    

    安装好后:在main.js中进行配置,参考上面main.js文件中的注释。

    四、进程通信

    项目构建完成后,这里开始讲解一下,react的项目和electron结合使用中的一个应用问题。先把需求提出来,如下图,我们需要在页面中点击右上角最小化时将页面窗口最小化(点击×时的功能以此类推),当点击登录时修改窗口大小,并展示直播页面。


    直播器2.gif

    要完成这个功能,要使用到Electron的API,这就要先从electron应用结构来说起,electron结构中分为主进程和渲染器进程,如下是electron官网的一段话。

    image.png
    意思就是说,main.js就是主进程,在主进程中打开的一个web页面就是一个渲染进程,这个web页面也就是该项目中的这个index.html,并且可以直接web页面上通过nodejs的api进行系统级的交互。
    如果我们没有使用react,那么没有什么问题,但是在react引入electron就会报错了。所以,要在react中使用,就需要提前将electron赋值给window.electron 以方便使用。在index.html的head中增加了一句js,如下图:
    <script>global.electron = require('electron')</script>
    

    此时,回想一下需求,点击“—”时最小化,我们发现触发事件的ui在web页面(react组件)中,而想要操作的mainWindow对象(主进程中打开的那个页面)却在主进程中。所以,尝试一个解决方案,让web页面(react组件)和主进程进行通信。
    实现进程通信使用到的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;
    

    如上点击时执行minWindow,引入ipcRender发送一个消息”min”,main.js中有对应的ipcMain进行监听,请看如下:

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

    因此,主进程收到消息后,即可对窗口进行处理为最小化,而登录功能与此类似,传递消息到主进程同时跳转页面,主进程收到消息后执行窗口最大化,因此就实现了最初的需求。
    同理,当组件有其他操作需要主进程作出反馈时,也可以使用此方案。

    相关文章

      网友评论

        本文标题:Electron+React 快速搭建一个桌面应用

        本文链接:https://www.haomeiwen.com/subject/navrmqtx.html