electron个人学习笔记
一、electron简单了解
Electron 是一个跨平台的、基于 Web 前端技术的桌面 GUI 应用程序开发框架。可以使用 HTML、CSS 来绘制界面和控制布局,使用 JavaScript 来控制用户行为和业务逻辑,使用 Node.js 来通信、处理音频视频等,几乎所有的 Web 前端技术和框架(jQuery、Vue、React、Angular 等)都可以应用到桌面 GUI 开发中。
二、开发前基本要求
需要安装 Node.js。 建议使用最新的LTS版本
要检查 Node.js 是否正确安装
node -v
npm -v
三、手动搭建一个 electron 项目
- 创建一个my-electron-app文件夹并初始化npm包
mkdir my-electron-app && cd my-electron-app
npm init
生成package.json文件
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"author": "xiao ming",
"license": "MIT"
}
electron
包安装到应用的开发依赖中
npm install --save-dev electron
package.json
配置文件中的scripts
字段下增加一条start
命令:
{
"scripts": {
"start": "electron ."
}
}
//start命令能让您在开发模式下打开您的应用
- 项目启动
npm start
-
创建项目报错点:
项目中有electron,但是运行electron . 报错
如果在项目中已经安装了 Electron 模块,但是运行
electron .
命令时仍然出现错误,可能是以下原因导致的:-
你的电脑上没有安装 Electron。在命令行中运行以下命令安装最新版本的 Electron:
npm install -g electron
-
当前目录不是项目根目录。请进入项目的根目录,然后再次尝试运行
electron .
命令。 -
项目中缺少必要的文件。请检查项目的目录结构和文件,确保你已经正确设置了项目。
-
如果你使用的是 Windows 操作系统,可能是因为 Windows 的路径格式与 Electron 不兼容导致的。你可以尝试使用 Unix 风格的路径格式,例如使用正斜杠
/
而不是反斜杠\
。
用electron . 启动项目和npm start启动项目的区别
electron .
和npm start
都可以用来启动 Electron 应用程序,但是它们的区别在于:electron .
是直接启动 Electron 模块,并指定要运行的应用程序文件的路径。这个命令只能在已经安装了 Electron 模块的电脑上运行。npm start
则是通过 package.json 文件中的 scripts 配置项来启动应用程序。默认情况下,这个命令会执行electron .
命令,但是你可以通过修改 scripts 配置项来指定其他命令来启动应用程序。npm start
还可以用来执行其他的命令,例如编译应用程序、运行测试等。
因此,
electron .
和npm start
都可以用来启动 Electron 应用程序,但是electron .
更适合用来启动单个应用程序,而npm start
更适合用来管理多个应用程序和执行其他的命令。 -
-
在跟目录下新建一个index.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Hello World!</h1> //将功能添加到您的网页内容 <script src="./renderer.js"></script> </body> </html>
-
在根目录下新建一个main.js文件为主进程
// 导入app模块 它控制应用程序的事件生命周期。 // 导入BrowserWindow 它创建和管理应用程序窗口。 const { app, BrowserWindow } = require('electron') const path = require('path') //创建浏览器窗口 function createWindow () { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js') } }) // 加载 index.html win.loadFile('index.html') } app.whenReady().then(() => { createWindow() app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } })
-
新建一个预加载脚本文件
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]) } })
-
打包分发应用程序,最快捷的打包方式是使用 Electron Forge。
- 将 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
3.Electron-forge 会创建 out
文件夹,您的软件包将在那里找到
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pSUB0CpV-1677737865577)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230224133907316.png)]
四、Electron 主进程和渲染进程
- 关于主进程和渲染器进程
package.json 中定义的入口被称为主进程。 在主进程中实例化 BrowserWindow 创建的
Web 页面被称为渲染进程。一个 Electron 应用只有一个主进程,但是可以有多个渲染进程,
每个 Electron 中的 web 页面运行在它自己的渲染进程中。
主进程使用 BrowserWindow 实例创建页面。 每个 BrowserWindow 实例都在自己的
渲染进程里运行页面。 当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终
止。
五、Electron 主 进 程 和 渲 染 进 程 中 使 用 Nodejs 以 及Nodejs 第三方模块
- 主进程中使用Nodejs模块
Electron 主进程中无需任何配置就可以使用 nodejs 模块。
- 渲染进程中使用 Nodejs 模块
BrowserWindow 中通过 preload 加载的 js 文件可以直接使用 nodejs 模块
如果不使用 preload 加载的 js,Electron5.x 之后没法在渲染进程中直接使用 nodejs,
如果我们想在渲染进程中使用 nodejs 的话需要进行如下配置。
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
// BrowserWindow 构造器中将路径中的预加载脚本传入 webPreferences.preload 选项
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true, //npm install @electron/remote --save
enableRemoteModule: true,
contextIsolation: false,
}
})
// 加载 index.html
win.loadFile('index.html')
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LDQRYSVh-1677737865580)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230224135139283.png)]
六、Electron技术架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ufDcvEf-1677737865582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230224140931848.png)]
- Chromium: 支持最新特性的浏览器 (支持ES6…)
- Nodejs :javascript运行时,可实现文件的读写功能等
- NataivAPI:提供统一的原生界面功能(可以与操作系统进行通信,做快捷键,获取底层硬件的设备信息等)
七、Electron的工作流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GoKXgt2G-1677737865582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230224141814710.png)]
桌面应用:运行在操作系统上的一款软件,软件中的功能实现是通过NativeAPI跟操作系统进行交互
八、生命周期
生命周期事件
- ready app初始化完成
- dom-ready 一个窗口中的文本加载完成
- did-finsh-load 导航完成时触发
- window-all-closed 所有窗口都关闭时触发
- before-quit 在关闭窗口时触发
- will-quit 在窗口即将退出时触发
- quit 当所有窗口被关闭时触发
- closed 当窗口关闭时触发,此时应删除窗口引用
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
console.log('444---window-all-closed');
})
app.on('ready',()=>{
console.log("1111---ready");
})
app.on ('close',()=>{
console.log("888---closed");
})
app.on ('quit',()=>{
console.log("777---quit");
})
app.on ('before-quit',()=>{
console.log("666---before-quit");
})
app.on ('will-quit',()=>{
console.log("555---will-quit");
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1qLPxuAC-1677737865584)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230224170927007.png)]
九、窗口尺寸
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8QCYPaB-1677737865584)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230227093613537.png)]
十、父子窗口及模态窗口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LtOyZUcH-1677737865586)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230227131213635.png)]
十一、自定义菜单
1.导入Menu模块
const {
app, BrowserWindow, ipcMain,Menu} = require('electron')
2.定义需要的菜单项,// 窗口创建后,页面加载之前,进行自定义菜单设置
let menuTemp = [
{
label:'文件'
},
{
label:'编辑'
}
]
// 利用上述的模板生成一个菜单
let menu = Menu.buildFromTemplate(menuTemp)
// 将上述的自定义菜单添加到应用里
Menu.setApplicationMenu(menu)
3.二级菜单的设置
let menuTemp = [
{
label:'文件',
submenu:[ //设置二级菜单
{
label:'打开文件'
},
// 二级菜单之间添加分割线
{
type:'separator'
},
{
label:'关闭文件'
},
{
label:'关于'
},
]
},
{
label:'编辑'
}
]
总结:
要在Electron中实现自定义菜单,你需要使用Menu
模块来创建一个菜单模板,然后使用Menu.buildFromTemplate()
方法将其转换为一个菜单对象,最后通过Menu.setApplicationMenu()
方法将其设置为应用程序的菜单。
const {
app, Menu } = require('electron')
// 定义菜单模板
const template = [
{
label: '菜单1',
submenu: [
{
label: '子菜单1' },
{
label: '子菜单2' }
]
},
{
label: '菜单2' }
]
// 将菜单模板转换为菜单对象
const menu = Menu.buildFromTemplate(template)
// 设置菜单为应用程序菜单
Menu.setApplicationMenu(menu)
// 当应用程序完成启动时,显示一个提示框
app.whenReady().then(() => {
const win = new BrowserWindow({
width: 800, height: 600 })
win.loadFile('index.html')
dialog.showMessageBox(win, {
message: '应用程序已启动!' })
})
注意点:electron使用console.log输出乱码问题
我们需要用到