官方网站:https://www.electronjs.org/ 开发文档:https://www.electronjs.org/docs 开发API:https://www.electronjs.org/zh/docs/latest/api/app

注意:如果用的是最新的electron,应该看最新的文档,有可能出现api不兼容的问题。

1.功能介绍:
Electron 基于 Chromium 和 Node.js, 让你可以使用 HTML, CSS 和 JavaScript 构建跨平台桌面应用。Electron 兼容 Mac、Windows 和 Linux,可以构建出三个平台的应用程序。

懂前端的同学学习electron上手很快。VScode,Whatsapp等都是使用electron开发。

2.如何安装:
打开scode,创建一个项目,使用终端执行 npm i -D electron@latest。使用yarn也可以。
配置文件:项目根目录下 package.json

{
  "name": "electron",
  "version": "1.0.0",
  "description": "高效工具",
  "main": "main.js",
  "scripts": {
    "start": "chcp 65001 && electron .",
    "build": "electron-builder ."
  },
  "build": {
    "appId": "win.electron.com",
    "asar": "false",
    "win": {
      "icon": "logo.ico"
    }
  },
  "author": "andy",
  "license": "ISC",
  "devDependencies": {
    "electron": "^7.0.0",
    "electron-builder": "^21.2.0"
  },
  "dependencies": {
    "iconv-lite": "^0.5.0",
    "uglify-js": "^3.6.2",
    "xmldom": "^0.1.27"
  }
}

运行方法:按F5或者 在终端执行 npm run start
发布方法:在终端执行 npm run build

3.运行原理:
Electron 包含三个核心:

Chromium 用于显示网页内容。
Node.js 用于本地文件系统和操作系统。
自定义 APIs 用于使用经常需要的 OS 本机函数。

用 Electron 开发应用程序就像构建一个带有网页界面的 Node.js 应用程序或构建无缝集成的网页。Electron 有两种进程:主进程和渲染进程。Html以及通过网页引入的js即可理解为渲染进程。

主进程通过创建 BrowserWindow 实例来创建 网页。 每一个 BrowserWindow 实例在其渲染过程中运行网页, 当一个 BrowserWindow 实例被销毁时,对应的渲染过程也会被终止。主进程 管理 所有网页及其对应的渲染进程。

渲染进程只能管理相应的网页, 一个渲染进程的崩溃不会影响其他渲染进程。渲染进程通过 IPC 与主进程通信在网在页上执行 GUI 操作。 出于安全和可能的资源泄漏考虑,直接从渲染器进程中调用与本地 GUI 有关的 API 受到限制。

进程之间的通信可以通过 Inter-Process Communication(IPC) 模块进行:ipcMainipcRenderer

4.如何使用
4.1 main.js

const electron=require('electron');
	//主进程
	const ipcMain =electron.ipcMain;
	const dialog=electron.dialog;
	const webContents = electron.webContents;
    const cp=require("child_process");
    const { app, BrowserWindow,Menu } = require('electron')
    const path = require('path')

    // 保持对window对象的全局引用,如果不这么做的话,当JavaScript对象被
    // 垃圾回收的时候,window对象将会自动的关闭
    let win

    function createWindow () {
      // 创建浏览器窗口。
      win = new BrowserWindow({
        width: 376,
        height: 728,
        minWidth:360,
        minHeight:640,
        resizable:true,
        movable:true,
        title:"工具",
        icon:path.join(__dirname, 'logo.ico'),
        webPreferences: {
          nodeIntegration: true,
          contextIsolation:false
        }
      })
      //显示主菜单
      win.setMenu(null);
      win.webContents.on('context-menu', function (e, params) {
        menu.popup(win, params.x, params.y);
        console.log(e);
      })
      // 加载index.html文件
      win.loadFile('index.html')
      // 打开开发者工具
      //win.webContents.openDevTools();      
      global.mainWindow=win;

      // 当 window 被关闭,这个事件会被触发。
      win.on('closed', () => {
        // 取消引用 window 对象,如果你的应用支持多窗口的话,
        // 通常会把多个 window 对象存放在一个数组里面,
        // 与此同时,你应该删除相应的元素。
        win = null
      })
    }

    // Electron 会在初始化后并准备
    // 创建浏览器窗口时,调用这个函数。
    // 部分 API 在 ready 事件触发后才能使用。
    app.on('ready', createWindow)

    // 当全部窗口关闭时退出。
    app.on('window-all-closed', () => {
      // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
      // 否则绝大部分应用及其菜单栏会保持激活。
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })

    app.on('activate', () => {
      // 在macOS上,当单击dock图标并且没有其他窗口打开时,
      // 通常在应用程序中重新创建一个窗口。
      if (win === null) {
        createWindow()
      }
    })

4.2 index.html

<!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8"/>
        <title>工具</title>
		<style>
			body{
				margin: 0px;
				padding: 0px;
			}
		</style>
      </head>
      <body>
		<div>
			<input id="btnOpenProj" type="button" value="菜单1" />
			<input id="btnLookProj" type="button" value="菜单2" title="菜单2"/>
			<input id="btnLookProj" type="button" value="菜单3" title="菜单3"/>
		</div>
		<script>require("./render.js")</script>
      </body>
    </html>

4.3 render.js

const electron = require('electron');
//渲染进程
const render = electron.ipcRenderer;
//主进程
const remote = electron.remote;
//菜单
var template = [ {
				label: '图片',
				submenu: [{
					id:'btnImage1',
				  	label: '图片1',
					click:clickMenu
				}, {
					id:'btnImage2',
				  	label: '图片2',
				  	click:clickMenu
				}]
			  }, {
				label: '音乐',
				submenu: [{
					id:'btnMusic1',
				  	label: '音乐1',
					click:clickMenu
				},{
					id:'btnMusic2',
				  	label: '音乐2',
					click:clickMenu
				}]
			  }];
		
let topMenu=Menu.buildFromTemplate(template);
Menu.setApplicationMenu(topMenu);
//菜单点击事件
function clickMenu(menuItem,win,event){
	console.log("点击菜单:",menuItem.id,menuItem.label);
}