本文中的所有代码均存放在https://github.com/MADMAX110/my-electron-app
Electron是什么?
Electron是一个开源的框架,可以使用JavaScript, HTML和CSS来构建跨平台的桌面应用程序。Electron的核心是由Chromium和Node.js组成,它们分别提供了渲染和主进程的功能。Electron的优势在于它可以利用Web技术来开发用户界面,同时也可以访问本地资源和系统API。嵌入Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建跨平台应用 ——不需要本地开发经验。
Electron的工作原理
它会创建一个主进程和一个或多个渲染进程。主进程负责管理应用程序的生命周期,创建和控制浏览器窗口,以及与操作系统交互。渲染进程则负责显示Web页面,并执行其中的JavaScript代码。主进程和渲染进程之间可以通过IPC(Inter-Process Communication)模块进行通信。
要开始使用Electron,首先需要安装Node.js和npm(Node Package Manager)。然后,可以使用npm来安装Electron,并创建一个基本的项目结构。
基本要求
在进行Electron进行开发之前,需要安装Node.js。
Node.js是一个基于Chrome V8 JavaScript引擎的JavaScript运行环境。它允许JavaScript代码在服务器端执行,并且拥有丰富的包生态系统。
Node.js主要功能包括:
- 事件驱动:Node.js使用事件驱动模型,当web server有请求的时候就会触发一个事件,然后响应的函数就会被调用,所以不会造成线程阻塞。
- 非阻塞I/O:Node.js使用libuv库,它的非阻塞I/O可以处理大量并发请求。
- 单线程:Node.js是单线程的,所以没有线程切换的开销,性能很高。不过在CPU密集任务下性能会受限。
- 高性能:使用Google V8引擎,性能很高,非常适合I/O密集型web应用。
- 丰富生态:有海量的第三方包,包管理工具npm,可以方便地实现各种功能。
- 跨平台:可以在Windows、MacOS、Linux等不同平台上运行。
Node.js典型应用场景:
- I/O密集型web应用:高并发请求处理,如聊天服务器,推送服务等。
- API编程:使用Express等框架可以方便地编写API。
- 测试环境:Javascript在前后端通用,方便编写测试用例。
- 工具开发:许多JavaScript工具都是用Node.js开发的,如grunt、gulp、webpack等。
- 游戏服务器开发:利用Node.js的高性能和低延时,适合开发游戏服务器。
- 命令行程序:可以使用Node.js编写各种CLI工具。
总之,Node.js是一个功能强大的JavaScript运行环境。因为其高性能、高并发、事件驱动等特征,目前已经在许多场景下取代了传统的服务器端技术,是一门非常值得学习的技能。
NodeJs下载地址:https://nodejs.org/en/download,进入选择下载适合你操作系统的版本,
双击下载后的安装包运行,一直下一步
点击树形图标来选择你需要的安装模式安装即可
勾选安装必须组件,以免以后出现不必要的麻烦,继续安装即可。
安装完后,可以在终端输入node -v和npm -v。若能正确输出nodejs和npm的版本信息,则安装成功。
创建你的应用程序
Electron 应用程序遵循与其他 Node.js 项目相同的结构。 首先创建一个文件夹并初始化 npm 包。
打开终端、输入以下指令
mkdir my-electron-app
cd my-electron-app
npm init
其代表创建一个my-electron-app文件夹并进入,然后init初始化命令会提示在项目初始化配置中设置一些值,设置完之后文件夹中会出现一个package.json文件,在init过程中设置的值错误了也没有关系,可以改动json文件中相应的选项即可。更改完成的json文件应该像这样。
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"author": "FYC",
"license": "MIT"
}
然后再执行
npm install --save-dev electron
将electron包安装到应用的开发依赖中。
再在刚才的package.json配置文件中的scripts字段下增加一条start命令。
{
“scripts”: {
“start”: “electron .”
}
}
start命令能让您在开发模式下打开应用。
运行主进程
任何 Electron 应用程序的入口都是 main 文件。 这个文件控制了主进程,它运行在一个完整的Node.js环境中,负责控制您应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程。执行期间,Electron 将依据应用中 package.json配置下main字段中配置的值查找此文件。
要初始化这个main文件,需要在您项目的根目录下创建一个名为main.js的空文件。
创建完成之后,就可以运行npm start命令了,然而这时候不会做任何事情,因为还没有在main.js中添加任何代码。
创建页面
在可以为我们的应用创建窗口前,我们需要先创建加载进该窗口的内容。 在Electron中,各个窗口显示的内容可以是本地HTML文件,也可以是一个远程url。这里采用本地HTML的方式。 在项目根目录下创建一个名为index.html的文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>你好!</title>
</head>
<body>
<h1>你好!</h1>
我们正在使用 Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
和 Electron <span id="electron-version"></span>.
</body>
</html>
在窗口中打开页面
现在有了一个页面,要将它加载进应用窗口中,需要两个Electron模块。
app 模块:它控制应用程序的事件生命周期。
BrowserWindow 模块:它创建和管理应用程序 窗口。
在main.js文件头部加入下列代码将两个模块导入作为CommonJS模块:
const { app, BrowserWindow } = require('electron')
然后,在main.js中添加一个createWindow()方法将index.html加载进一个新的BrowserWindow实例。
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
如此,便可调用createWindow函数打开窗口,在Electron中,只用在app模块的ready事件被激发后才能创建浏览器窗口。可以使用app.whenReady()来监听该事件,在whenReady成功后调用createWindow。继续在main.js中加入以下代码即可。
app.whenReady().then(() => {
createWindow()
})
此时再运行npm start便可打开之前创建好的index界面。
管理窗口的生命周期
虽然现在可以打开一个浏览器窗口,还需要额外的模板代码使其看起来像各平台原生的。应用程序再每个操作系统下都有不同的行为,Electron将再app中实现这些约定的责任交给开发者。
一般而言都可以使用process.platform属性获取当前运行的操作系统。
1、关闭所有窗口时退出应用 (Windows & Linux):
在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。
为了实现这一点,你需要监听 app 模块的 ‘window-all-closed’ 事件。如果用户不是在 macOS(darwin) 上运行程序,则调用 app.quit()。
再main.js中加入以下代码即可实现:
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
2、如果没有窗口打开则打开一个窗口 (macOS)
当 Linux 和 Windows 应用在没有窗口打开时退出了,macOS 应用通常即使在没有打开任何窗口的情况下也继续运行,并且在没有窗口可用的情况下激活应用时会打开新的窗口。
为了实现这一特性,监听 app 模块的 activate 事件。如果没有任何浏览器窗口是打开的,则调用 createWindow() 方法。
因为窗口无法在 ready 事件前创建,你应当在你的应用初始化后仅监听 activate 事件。 通过现有的 whenReady() 回调中附上您的事件监听器来完成这个操作。
在main.js中修改whenReady如下即可实现:
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
还可以通过预加载脚本从渲染器访问Node.js
现在要做的使输出Electron版本号和它的依赖项到你的web页面上。
预加载脚本在渲染器进程加载之前加载,并有权访问两个 渲染器全局 (例如 window 和 document) 和 Node.js 环境。
在文件根目录创建一个名为 preload.js 的新脚本如下:
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
上面的代码访问 Node.js process.versions 对象,并运行一个基本的 replaceText 辅助函数将版本号插入到 HTML 文档中。
要将此脚本附加到渲染器流程,请在现有的 BrowserWindow 构造器中将路径中的预加载脚本传入 webPreferences.preload 选项。
在main.js中添加修改如下代码
// 需在当前文件内开头引入 Node.js 的 'path' 模块
const path = require('path')
// modify your existing createWindow() function
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
// ...
这里使用了两个Node.js概念:
__dirname 字符串指向当前正在执行脚本的路径 (在本例中,它指向你的项目的根文件夹)。
path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串。
我们使用一个相对当前正在执行JavaScript文件的路径,这样相对路径将在开发模式和打包模式中都将有效。
此时,整个程序的代码已经完成,可以在终端运行npm start来查看最终效果。
将功能添加到您的网页内容中
对于与您的网页内容的任何交互,您想要将脚本添加到您的渲染器进程中。 由于渲染器运行在正常的 Web 环境中,因此您可以在 index.html 文件关闭 标签之前添加一个
<script src="./renderer.js"></script>
renderer.js 中包含的代码可以在接下来使用与前端开发相同的 JavaScript API 和工具。例如使用 webpack 打包并最小化代码,或者使用 React 来管理用户界面。
打包并分发开发好的应用程序
最快捷的打包方式是使用Electron Forge
1、将 Electron Forge 添加到应用的开发依赖中,并使用其"import"命令设置 Forge 的框架:
npm install --save-dev @electron-forge/cli
npx electron-forge import
✔ Checking your system
✔ Initializing Git Repository
✔ Writing modified package.json file
✔ Installing dependencies
✔ Writing modified package.json file
✔ Fixing .gitignore
We have ATTEMPTED to convert your app to be in a format that electron-forge understands.
Thanks for using "electron-forge"!!!
2、使用 Forge 的 make 命令来创建可分发的应用程序:
npm run make
> my-electron-app@1.0.0 make /my-electron-app
> electron-forge make
✔ Checking your system
✔ Resolving Forge Config
We need to package your application before we can make it
✔ Preparing to Package Application for arch: x64
✔ Preparing native dependencies
✔ Packaging Application
Making for the following targets: zip
✔ Making for target: zip - On platform: darwin - For arch: x64
Electron-forge 会创建 out 文件夹,打包好的软件包将在那里找到。