TMaize Blog

使用Electron

如果你可以建一个网站,你就可以建一个桌面应用程序

Electron 是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架,它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可

安装

Electron是基于Nodejs的,Nodejs的安装就不说了

npm install -g electron

# 安装打包工具

npm install -g electron-packager

基本使用

  1. 创建package.json,没有模板的话可以使用npm init

  2. 在package.json中main指定的js文件,也就是electron主进程进行初始化

  3. 看看api,主进程能使用那些,渲染进程能使用拿下,都有什么可以使用的属性,方法

  4. 由于使用Nodejs,一些模块会无法导出到windows,比如jQuery,使用Nodejs规范的require即可

  5. 打包的使用

    如下命令会在./release下生成outDirName-win32-x64文件夹

     electron-packager . outDirName --out=release --platform=win32 --arch=x64 --version=1.0.0 --electron-version=1.8.4 --overwrite --prune=true --icon=./resource/glee.ico --ignore=temp/
    
  6. 了解以上基本就可以了

隐藏Frame

关于外部窗口的隐藏有些要注意的地方

窗口通讯

electron中,从package.json的main载入的js文件就是主进程,由主进程load出来的页面就是渲染进程

渲染进程可以有多个,主进程只有一个”main.js”

主进程和渲染进程之间通信,可以使用ipcMain(主进程)和ipcRenderer(渲染进程)来通信,也可以使用remote模块来通信

所以最常见的就是主进程做中转来实现多个窗口之间的通信

一个案例

01

# 调试
npm run start
# 打包
npm run package-win

package.json

{
  "name": "eee",
  "version": "1.0.0",
  "description": "666",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "package-win": "electron-packager . outDirName --out=release --platform=win32 --arch=x64 --version=1.0.0 --electron-version=1.8.4 --overwrite --prune=true --icon=./resource/glee.ico --ignore=temp/"
  },
  "author": "",
  "license": "ISC"
}

main.js

const url = require('url')
const path = require('path')
const electron = require('electron');

const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const ipc = electron.ipcMain

let devModel = false;
// 判断是否是mac系统
let isMac = process.platform === 'darwin'
let appIcon = "./resource/dock.png";

// 打开的一个窗口,暴露在全局便于管理
let mainWindow;

function createWindow() {

    //创建一个窗口,可以创建多个
    mainWindow = new BrowserWindow({
        width: devModel ? 1000 : 380,
        height: 610,
        resizable: false,
        title: "Demo",
        icon: appIcon,
        frame: false,
        transparent: true
    });

    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'app/index.html'),
        protocol: 'file:',
        slashes: true
    }));

    // 显示开发者工具
    if (devModel) {
        mainWindow.webContents.openDevTools();
    }

    if (isMac) {
        app.dock.setIcon(appIcon);
    }

    //回收资源
    mainWindow.on('closed', () => {
        mainWindow = null;
    });
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
    if (!isMac) {
        app.quit();
    }
});

ipc.on('window-min', function () {
    mainWindow.minimize();
})

ipc.on('window-close', function () {
    mainWindow.close();
})

app/index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
</head>

<body>
    <div id="container">

        <h1 style="-webkit-app-region: drag">
            <span>Hello</span>
            <span style="-webkit-app-region: no-drag">
                <input type="button" value="max" id="min">
                <input type="button" value="close" id="close">
            </span>
        </h1>
        <input type="button" value="请求http://blog.tmaize.net/" id="req">
        <div id="req-out"></div>
    </div>
    <style>
        * {
            user-select: none;
            cursor: default;
        }

        html,
        body {
            height: 100%;
            width: 100%;
            box-sizing: border-box;
            padding: 8px;
            margin: 0;
        }

        #container {
            height: 100%;
            width: 100%;
            -moz-box-shadow: 0px 0px 8px #2B2B2B;
            -webkit-box-shadow: 0px 0px 8px #2B2B2B;
            box-shadow: 0px 0px 8px #2B2B2B;
            background-color: white;
            box-sizing: border-box;
            overflow: auto;
        }
    </style>

    <script>
        //由于采用了nodejs的引用方式直接引用js文件全局变量无法导出
        window.$ = window.jQuery = require("./js/jquery.min");
        //渲染进程的通讯模块
        window.ipc = require('electron').ipcRenderer;
        //网络请求
        window.http = require('http');
        $(function () {

            $('#min').click(function () {
                ipc.send('window-min');
            });

            $('#close').click(function () {
                ipc.send('window-close');
            });

            $('#req').click(function () {
                http.get('http://blog.tmaize.net/', function (res) {
                    res.setEncoding('utf8');
                    res.on('data', function (chunk) {
                        $('#req-out').text($('#req-out').text() + chunk);
                    });
                });

            });
        });
    </script>
</body>

</html>