使用create-react-app编写Electron app

目录

  • Electron简介

    • 打造你第一个 Electron 应用
    • 下一步
  • 整合

    • create-react-app创建工程
    • 整合antd
      • 修改package.json
      • config-overrides.js
      • src/App.js
      • 运行
    • 整合Electron
      • 安装Electron库
      • 添加Electron启动文件
      • 配置Electron入口
      • 修改界面
      • 调试运行
      • 生产环境运行
  • 分发应用

    • 简介
    • electron-builder 生成安装包
      • 安装electron-builder
      • 配置icon
      • 配置package.json
      • 生成安装包
  • 参考文档

Electron简介

Electron是一个利用javascript/css/html来开发跨平台(Mac/Windows/Linux)桌面应用的框架。
VS Code/Atom/GitHub Desktop等软件是基于Electron编写的。

# 可以简单这样理解
Electron = nodejs + chrome内核
  • 因为内置一个chrome内核,所以开发者可以使用javascript/html/css来构建界面;这一部分运行在渲染进程中。
  • 因为内置nodejs环境,所以可以访问计算机本地的资源:读写磁盘文件、创建进程、本地通知、、、;这一部分运行在主进程中。

打造你第一个 Electron 应用

下一步

Electron并没有限制我们使用什么技术/框架来渲染UI,我们希望结合Electron+create-react-app+redux+react router+antd共同打造一个高效、快速的、工程化的开发体验。

整合

完整的示例可从这里下载

create-react-app创建工程

# 使用create-react-app创建工程
$ create-react-app demo-app

整合antd

# 添加antd库
$ yarn add and

# 这个库可以让我们不必运行CRA的eject
$ yarn add react-app-rewired --dev

# 按需加载
$ yarn add babel-plugin-import --dev
修改package.json
# 修改 start/build/test 脚本
...
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
}
...
config-overrides.js

在项目的根目录下增加一个config-overrides.js文件

const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
    config = injectBabelPlugin(['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }], config);
    return config;
};
src/App.js
import React, { Component } from 'react';
import { Button } from 'antd';
import './App.css';

class App extends Component {
  render() {
    return (
      
); } } export default App;
运行
# 调试运行,访问:http://localhost:3000/
$ npm start

# 生成release包
$ npm build

整合Electron

安装Electron库
# 安装electron
$ yarn add electron --dev
添加Electron启动文件

添加public/electron.js

// `主进程`入口
const electron = require('electron');
const platform = require('os').platform();  // 获取平台:https://nodejs.org/api/os.html#os_os_platform
// 控制app生命周期.
const app = electron.app;
// 浏览器窗口.
const BrowserWindow = electron.BrowserWindow;

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

console.log(platform);

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

function createWindow()
{
    // 创建一个浏览器窗口.
    mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: {
        webSecurity: false, // 这样可以在 webview 中加载/显示本地计算机的图片。
    } });

    // 这里要注意一下,这里是让浏览器窗口加载网页。
    // 如果是开发环境,则url为http://localhost:3000(package.json中配置)
    // 如果是生产环境,则url为build/index.html
    const startUrl = process.env.ELECTRON_START_URL || url.format({
        pathname: path.join(__dirname, '/../build/index.html'),
        protocol: 'file:',
        slashes: true
    });
    // 加载网页之后,会创建`渲染进程`
    mainWindow.loadURL(startUrl);

    // 打开chrome浏览器开发者工具.
    if(startUrl.startsWith('http'))
    {
        mainWindow.webContents.openDevTools();

        // 加载 react/redux 调试工具(如果有需要的话)
        if('darwin' === platform)
        {
            BrowserWindow.addDevToolsExtension('/Users/issuser/Library/Application\ Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/3.1.0_0');
            BrowserWindow.addDevToolsExtension('/Users/issuser/Library/Application\ Support/Google/Chrome/Default/Extensions/lmhkpmbekcpmknklioeibfkpmmfibljd/2.15.2_0');
        }
    }

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        mainWindow = null
    });
}

app.on('ready', createWindow);

app.on('window-all-closed', function () {
    if (process.platform !== 'darwin')
    {
        app.quit();
    }
});

app.on('activate', function ()
{
    if (mainWindow === null)
    {
        createWindow();
    }
});

// 这是一个示例,展示了`渲染进程`发送了`chooseFolder `事件后,`主进程`打开选择目录的对话框。
electron.ipcMain.on('chooseFolder', function(){
    const dialog = electron.dialog;
    dialog.showOpenDialog(mainWindow, {
        properties: ['openDirectory']
    });
});
配置Electron入口

package.json文件

{
  ...
  "main": "public/electron.js",
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "electron": "electron .",
    "electron-dev": "ELECTRON_START_URL=http://localhost:3000 electron ."
  },
  ...
}
修改界面
// src/App.js
// UI界面运行在`渲染进程`
import React, { Component } from 'react';
import { Button } from 'antd';
import './App.css';

// 渲染进程可以通过`ipcRenderer`向主进程发送消息。
const electron = window.require('electron');
const fs = electron.remote.require('fs');
const ipcRenderer  = electron.ipcRenderer;

class App extends Component {
    render() {
        return (
            
); } showNativeDialog() { // 选择文件示例 // const dialog = electron.remote.dialog; // dialog.showOpenDialog({ // properties: ['openDirectory'] // }, (filePaths)=>{ // console.log(filePaths); // }); ipcRenderer.send('chooseFolder'); } } export default App;
调试运行
# 调试运行web程序
$ npm start

# 调试运行electron,并用浏览器窗口(BrowserWindow)加载上面的web程序
$ npm run electron-dev
生产环境运行
# 编译生成web页面的release包,结果保存在build目录
$ npm run build

# 运行electron,并用浏览器窗口(BrowserWindow)加载build/index.html文件
$ npm run electron
使用create-react-app编写Electron app_第1张图片
效果图

分发应用

简介

我们希望将Electron的app打包成.app/.exe发布给其他人下载安装。
分发的方式有好几种:

  • 可以通过第三方
  • 也可以下载Electron官方提供的壳子app,然后把package.json/build目录/public目录放到壳子对应的目录下即可

详情见官网指南分发应用

electron-builder生成安装包

安装electron-builder
$ npm install electron-builder --save-dev
配置icon

放在public/icon.png,尺寸:512x512

配置package.json
{
  "name": "demo-app",
  // 配置app的名称
  "productName": "示例",
  "description": "描述信息",
  "author": "作者",
  "version": "0.1.0",
  "private": true,
  // 入口
  "main": "./public/electron.js",
  "homepage": "./",
  // 把dependencies里面的内容都放到devDependencies里面去
  "dependencies": {},
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject",
    "electron": "electron .",
    "electron-dev": "ELECTRON_START_URL=http://localhost:3000 electron .",
    "packager": "npm run build && rm -rf dist && electron-builder"
  },
  "build": {
    "appId": "com.isoftstone.apptools",
    "mac": {
      "category": "public.app-category.developer-tools"
    },
    "files": [
      {
        "from": "./",
        "to": "./",
        "filter": [
          "**/*",
          "!node_modules"
        ]
      },
      {
        "from": "./node_modules/image-size",
        "to": "./node_modules/image-size"
      }
    ],
    "directories": {
      "buildResources": "public"
    }
  },
  "devDependencies": {
    "antd": "^3.3.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-scripts": "1.1.1",
    "babel-plugin-import": "^1.6.6",
    "electron": "^1.8.3",
    "electron-builder": "^20.8.1",
    "electron-load-devtool": "^1.0.0",
    "image-size": "^0.6.2", // 这是一个第三方node模块
    "react-app-rewired": "^1.5.0"
  }
}

生成安装包
$ npm run packager
使用create-react-app编写Electron app_第2张图片
生成的安装包

参考文档

  • How to build an Electron app using create-react-app. No webpack configuration or “ejecting” necessary.
  • Electron官网
  • 如何使用 Electron 和 React 构建一个 APP

你可能感兴趣的:(使用create-react-app编写Electron app)