electron基础

2022/03/01 web跨平台框架

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

1、简介

  • Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 ChromiumNode.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。

2、进程、线程

  • 进程:正在进行的一个过程或者说一个任务。进程指的是程序的运行过程,而负责执行任务则是cpu。不同的进程不能相互沟通。
  • 线程:线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。同进程下的线程可以沟通。

electron也是基于Chromium,所以在electron中分为主进程main process和渲染进程renderer process

进程之间在Electron中想要通信可以使用IPC

3、创建项目

需要有node环境,使用npm或者yarn都行

mkdir my-electron-app && cd my-electron-app
npm init
npm install --save-dev electron
npm start

如果想看官网的demo

# 克隆项目
git clone https://github.com/electron/electron-quick-start

# 进入目录
cd electron-quick-start

# 安装依赖并运行
npm install && npm start

因为是基于node的,节省每次编译的时间,使用nodemon

npm install nodemon --save-dev

然后修改package.json

"scripts":{
  "start": "nodemon --watch main.js --exec \"electron .\""
}

意思是nodemon监听main.js,每次改变去执行electron .,而electron .执行的文件就是main.js,是在如下这个地方配置的

"main": "main.js"

3、主要文件

创建好项目,项目目录

  • main.js:主进程的文件
  • renderer.js:渲染进程的文件

4、创建窗口

清空main.js的内容,学习electron的第一个API:BrowserWindow:这个API目前只能在主进程main.js中使用。

const { app, BrowserWindow} = require('electron');

app.on('ready', ()=>{
  let mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      // 配置下面这个参数可以解决引入的js不生效的问题
      // 由于require可以直接请求运行客户机上的文件,容易引起安全问题,而在新的electron中被禁止,所以在contextIsolation为true时认为require不可以启用
      // contextIsolation默认为true
      contextIsolation: false 
    }
  })
	// 给当前窗口加载html文件
  mainWindow.loadFile('index.html');

  // 创建子窗口
  let secondWindow = new BrowserWindow({
    width: 400,
    height: 300,
    webPreferences: {
      nodeIntegration: true
    },
    parent: mainWindow
  })
  secondWindow.loadFile('second.html');
})

5、添加事件

在窗口里引用的HTML文件的里面可以引入js脚本

<!-- index.html -->


<h1>Hello World! 2s</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.

<!-- You can also require other files to run in this process -->
<script src="./renderer.js"></script>

在这个js里面可以操控DOM,也可以使用node 的API

// renderer.js
window.addEventListener('DOMContentLoaded', ()=>{
    document.getElementById('node-version').innerHTML = process.versions.node + '测试';
})

然后运行main.js就可以看到新的窗口上有内容了。

6、主进程和渲染进程通信

// main.js
const { app, BrowserWindow, ipcMain  } = require('electron');


app.on('ready', ()=>{
  // ....
  ipcMain.on('message', (event, arg)=>{
    event.reply('reply', arg)
  })
})


// renderer.js
const { ipcRenderer } = require('electron')

window.addEventListener('DOMContentLoaded', ()=>{
		
  // ....
    document.getElementById('send').addEventListener('click', ()=>{
        ipcRenderer.send('message', '这是一条发送过来的消息')
    })

    ipcRenderer.on('reply', (evenr, arg)=>{
        document.getElementById('message').innerHTML = arg;
    })
})

在HTML中

<!-- index.html  -->

<button id="send">发送</button>
<div id="message"></div>

ipc

6.1 remote

在Electron中的模块有些只能在主进程中使用、有些只能在渲染进程中使用、只有一小部分模块在主进程和渲染进程中都可以使用

Electron 中与 GUI 相关的模块只存在于主进程,而不在渲染进程中 ,为了能从渲染进程中使用它们,需要给主进程发送进程间消息。remote 模块提供了一种在渲染进程和主进程之间进行进程间通讯的简便途径,使用 remote 模块,可以调用主进程对象的方法,而无需显式地发送进程间消息

Electron10.x 以后要使用 remote 模块的必须得在 BrowserWindow 中开启。

const createWindow = () => {
    // 创建窗口
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            // 开启node
            nodeIntegration: true,
            contextIsolation: false,
            // 开启remote
            enableRemoteModule:true
        }
    });
}

具体使用:

在electron17.x之后,remote模块想要使用需要npm install

npm install --save @electron/remote

然后在主进程中配置引用

const { app, BrowserWindow, ipcMain  } = require('electron');

app.on('ready', ()=>{

  let mainWindow = new BrowserWindow({
    width: 1000,
    height: 800,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  }) 
	
  require("@electron/remote/main").initialize();
  require("@electron/remote/main").enable(mainWindow.webContents);
}) 

才可以在渲染进程中使用:

const { ipcRenderer } = require('electron')
const { BrowserWindow } = require("@electron/remote");

window.addEventListener('DOMContentLoaded', ()=>{
    
    document.getElementById('node-version').innerHTML = process.versions.node + '测试';
    document.getElementById('send').addEventListener('click', ()=>{
        ipcRenderer.send('message', '这是一条发送过来的消息')
        var win = new BrowserWindow({ width: 800, height: 600 });
        win.loadURL('https://baidu.com');
    })
    ipcRenderer.on('reply', (evenr, arg)=>{
        document.getElementById('message').innerHTML = arg;
    })
})

Search

    Table of Contents