React + Electron + Antd 写一个简单的计算器客户端

创建react项目

create-react-app calculator

引入electron

yarn add electron --dev

引入antd

yarn add antd

引入electron-is-dev,用来判断当前是开发环境还是生产环境

yarn add electron-is-dev

在public目录下加入electron.js, preload.js

electron.js

// Modules to control application life and create native browser window
const { app, BrowserWindow, Menu } = require("electron");
const path = require("path");
const isDev = require("electron-is-dev");

let mainWindow;

function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      preload: path.join(__dirname, "preload.js"),
    },
  });

  // 清除顶部菜单
  Menu.setApplicationMenu(null);

  if (isDev) {
    mainWindow.loadURL("http://localhost:3000");
    mainWindow.openDevTools();
    // mainWindow.webContents.openDevTools();
  } else {
    mainWindow.loadFile("./build/index.html");
  }

  mainWindow.on("closed", function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  createWindow();

  app.on("activate", function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", function () {
  if (process.platform !== "darwin") app.quit();
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

preload.js

// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
window.addEventListener("DOMContentLoaded", () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector);
    if (element) element.innerText = text;
  };

  for (const type of ["chrome", "node", "electron"]) {
    replaceText(`${type}-version`, process.versions[type]);
  }
});

修改package.json

{
  ...
   "main": "public/electron.js",
   "homepage": ".",
   "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "electron": "electron ."
    }
  ...
}

运行程序

# 运行react
yarn start

# 运行electron
yarn electron

每次都运行两个命令很麻烦,使用concurrently和wait-on,将两个命令放在一起运行

yarn add concurrently wait-on --dev

修改package.json

{
  ...
  "scripts": {
        "electron": "concurrently \"react-scripts start\" \"wait-on http://localhost:3000 && electron .\""
    }
  ...
}

客户端渲染使用react

计算器一般分为两块,一块显示计算结果,一块为按钮操作区,新建两个组件input-button.js, input-text.js

// # input-text.js

import React, { Component } from "react";
import { Input } from "antd";

const { TextArea } = Input;

class inText extends Component {
  render() {
    return (