Electron入门
- 1.简介
- 2.快速上手
- 3.热加载-自动刷新界面
- 4.主进程与渲染进程
- 5.调试
- 6.自定义菜单及简单应用
- 7.读取与保存文件
- 8.定义快捷键
- 9.主进程与渲染进程通讯
- 10.Electron打包发布
- 11.Electron结合Vue框架开发
1.简介
- 官网:https://www.electronjs.org/
- Electron是可以通过JavaScript、HTML和CSS构建桌面应用的框架,大大减少了公司对人员方面的需求,web端工程师就可以制作桌面应用,并且工程师只需把精力放在应用的核心上即可。
2.快速上手
由于Electron是基于Node.js的,故在使用Electron之前请确保已经安装Node.js,npm或cnpm(淘宝镜像)。
2.1安装Electron
1、在任意盘符下创建一个文件夹ElectronDemo(该名可自定义)
2、进入ElectronDemo文件夹下,按住shift,点击鼠标右键,选择运行powershell(或在VSCode终端运行)。
- 初始化package.json文件–npm init(一路回车即可)
- 安装Electron–cnpm I electron -s
2.2、配置入口文件
1、将main键的值改为mian.js,用于程序加载时首次打开的js
2、在scripts键中增加键值对"electron":“electron .”,用于启动时的简写,"electron"可以换成其他字符,比如strat,相应的运行语句也要发生改变,运行语句:npm run electron。具体如图所示:

2.3创建main.js文件
const { app, BrowserWindow} = require('electron')
//初始化界面
app.on('ready', () => {
const mainWindow= new BrowserWindow({ //创建窗口
width: 700,
height: 700
})
mainWindow.loadFile('./src/index.html') //加载初始html
})
- 根目录下创建src文件夹,在src文件夹下创建index.html
- 终端运行:npm run electron,效果图如下:

3.热加载-自动刷新界面
主要目的是应用于减少每次修改程序都需重新运行程序启动语句的问题。
- shell中运行–cnpm install --save-dev electron-reloader
- main.js中添加如下代码,具体代码如下:
const reloader = require('electron-reloader')
reloader(module)
const { app, BrowserWindow } = require('electron')
//热加载--自动刷新
const reloader = require('electron-reloader')
reloader(module)
//初始化界面
app.on('ready', () => {
const mainWindow= new BrowserWindow({ //创建窗口
width: 700,
height: 700
})
mainWindow.loadFile('./src/index.html') //加载初始html
})
4.主进程与渲染进程
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。故有了主进程与渲染进程。package.json 中 main 脚本的进程被称为主进程 。每个 Electron 中的 web 页面运行的进程叫渲染进程。该方案的主要优势在于Electron 用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互,而在普通的浏览器中,web页面无法访问操作系统的原生资源。
5.调试
- 主进程中调试:console.log(),代码将在终端控制台输出。
- 渲染进程调试:ctrl+shift+i调出调试面板,或在main.js中添加mainWindow.webContents.openDevTools(),加载界面时自动打开调试工具。
const { app, BrowserWindow } = require('electron')
//热加载--自动刷新
const reloader = require('electron-reloader')
reloader(module)
//初始化界面
app.on('ready', () => {
const mainWindow= new BrowserWindow({ //创建窗口
width: 700,
height: 700
})
mainWindow.loadFile('./src/index.html') //加载初始html
mainWindow.webContents.openDevTools() //自动打开调试工具
})
6.自定义菜单及简单应用
6.1修改Electron默认菜单
在根目录下创建menu.js文件,并将menu.js通过require引入到main.js中
const { BrowserWindow, Menu} = require('electron')
const template = [
{
label: '文件',
submenu: [
{
label: '新建窗口',
click: ()=>{
const newMainWindow = new BrowserWindow({
width: 300,
height: 300
})
newMainWindow.loadFile('./new.html')
}
}
]
},
{
label: '编辑',
submenu: [
{
label: '新建窗口'
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
const { app, BrowserWindow } = require('electron')
//热加载--自动刷新
const reloader = require('electron-reloader')
reloader(module)
//初始化界面
app.on('ready', () => {
const mainWindow= new BrowserWindow({ //创建窗口
width: 700,
height: 700
})
mainWindow.loadFile('./src/index.html') //加载初始html
mainWindow.webContents.openDevTools() //自动打开调试工具
require('./menu.js') //加载菜单js
})
6.2自定义个性化菜单
在main.js中的BrowserWindow中增加键值对frame: false,令原始菜单默认去掉,之后通过html中的ul li 自主创建个性化菜单。具体代码如下:
const mainWindow = new BrowserWindow({
frame: false
})
<div class="custom-menu">
<ul>
<li>新建窗口</li>
<li>关于我们</li>
</ul>
</div>
*{
margin: 0;
padding: 0;
}
.custom-menu{
height: 50px;
width: 100%;
background: pink;
-webkit-app-region:drag; /*实现拖动功能*/
}
.custom-menu ul{
list-style: none;
}
.custom-menu ul li{
float: left;
width: 80px;
line-height: 50px;
text-align: center;
margin-left: 10px;
-webkit-app-region:no-drag; /*li上去掉拖动功能,否则点击事件不好用*/
}
6.3在渲染进程中创建一个新窗口
- shell中运行安装:npm install --save @electron/remote
- 在主进程中给渲染进程打开权限
webPreferences: { //领渲染进程可以使用主进程里面的东西例如,BrowserWindow
// 开启node
nodeIntegration: true,
contextIsolation: false,
// 开启remote
enableRemoteModule: true
}
const { app, BrowserWindow } = require('electron')
//热加载--自动刷新
const reloader = require('electron-reloader')
reloader(module)
//初始化界面
app.on('ready', () => {
const mainWindow = new BrowserWindow({ //创建窗口
width: 700,
height: 700,
frame: false, //创建一个无边框的窗口,就是没有菜单
webPreferences: { //领渲染进程可以使用主进程里面的东西例如,BrowserWindow
// 开启node
nodeIntegration: true,
contextIsolation: false,
// 开启remote
enableRemoteModule: true
}
})
mainWindow.loadFile('./src/index.html') //加载初始html
mainWindow.webContents.openDevTools() //自动打开调试工具
require('./menu.js')
})
- index.html中添加一个按钮,用于打开一个新的窗口
<li class="new-window">新建窗口</li>
- 创建一个index.js并在index.html中引入
// remote 通过remote使用主进程的方法
const { BrowserWindow} = require('@electron/remote')
const newWindow = document.querySelector('.new-window') //获取节点
newWindow.onclick = function () { //触发点击事件
new BrowserWindow({
width: 200,
height: 300
})
}
6.4跳转浏览器打开一个地址
- index.html添加一个a标签
<a id="a1" href="https://www.itheima.com">打开浏览器</a>
- index.js中通过shell实现跳转
//引入shell
const { shell} = require('@electron/remote')
const allA = document.querySelectorAll('a') //获取节点
allA.forEach(item => { //遍历每一个节点绑定事件
item.onclick = function (e) {
e.preventDefault() //阻止默认行为,否则会在Electron中再次打开
shell.openExternal(item.href)
}
})
6.5将本地HTML文件在浏览器中打开
- 通过node.js中的path获取当前文件所在的路径,之后通过shell在浏览器中打开重构的路径
const { BrowserWindow, Menu, shell } = require('electron')
//自定义菜单
//定义菜单模板
const template = [
{
label: '办公工具',
submenu: [
{
label: '录屏工具',
click() {
var path = require("path") //利用node.js获取文件路径,__dirname代表当前文件路径
var wideoPath="file:///"+__dirname+"/src/Video/videoIndex.html"
console.log('resolve : ' + wideoPath);
shell.openExternal(wideoPath)
}
}
]
},
{
label: '关于我们'
}
]
//编译模板
const menu = Menu.buildFromTemplate(template)
//设置菜单
Menu.setApplicationMenu(menu)
7.读取与保存文件
- index.html增加两个按钮与一个文本域
<button onclick="openFile()">打开</button>
<button onclick="saveFile()">保存</button>
<textarea ></textarea>
- index.js通过dialog打开文件,获取文件路径,通过node.js中的fs进行保存。
const { dialog } = require('@electron/remote')
//读取文件
var fs = require('fs');
const textEl = document.querySelector('textarea')
const openFile = function () {
const res= dialog.showOpenDialogSync({
title: '读取文件',
buttonLabel: '读取',
filters: [
{name:"Cumtom File Type",extensions:['js']}
]
})
const filesContent = fs.readFileSync(res[0]).toString()
textEl.value=filesContent;
}
//保存文件
const saveFile = function () {
const res = dialog.showSaveDialogSync({
title: '保存文件',
buttonLabel: '保存文件',
filters: [
{name:'index',extensions:['js']}
]
})
fs.writeFileSync(res,textEl.value)
}
8.定义快捷键
8.1 主线程定义快捷键
- main.js中引入globalShortcut
const { app, BrowserWindow ,globalShortcut} = require('electron')
- ready中增加代码
globalShortcut.register('CommandOrControl+T', () => {
mainWindow.unmaximize() //窗口最小化
})
globalShortcut.register('CommandOrControl+M', () => {
mainWindow.maximize() //窗口最大化
})
globalShortcut.register('CommandOrControl+H', () => {
mainWindow.close() //关闭窗口
})
8.2渲染进程定义快捷键
- js中通过’@electron/remote’引入globalShortcut
const { globalShortcut } = require('@electron/remote')
globalShortcut.register('CommandOrControl+J', () => {
console.log('按下了ctrl+J')
})
9.主进程与渲染进程通讯
- 主进程中引入ipcMain,渲染进程中引入ipcRenderer,注意ipcRenderer本身就是渲染进程中的,不需要使用remote,可以直接使用electron。
const { app, BrowserWindow ,globalShortcut,ipcMain} = require('electron')
//接受渲染进程的通信
ipcMain.on('max-window', (event, arg) => {
if (arg=="max-window") {
return mainWindow.maximize(); //根据参数做出反应
}
mainWindow.unmaximize();
})
const {ipcRenderer } = require('electron')
//点击窗口最大化与最小化切换
let windowsize="unmax-window"
const maxWindow = function () {
windowsize=windowsize==="unmax-window"?"max-window":"unmax-window" //开关切换
ipcRenderer.send('max-window',windowsize) //给主进程通讯并传参
}
10.Electron打包发布
- 安装electron-packager:cnpm i electron-packager -D
- 在package.json的scripts中添加键值对
"build": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico"
{
"name": "electron20220415",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"electron": "electron .",
"build": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico"
},
"author": "",
"license": "ISC",
"dependencies": {
"@electron/remote": "^2.0.8",
"electron": "^18.0.4",
"electron-packager": "^15.4.0",
"electron-reloader": "^1.2.3"
},
"devDependencies": {}
}
- 在终端或者shell中运行npm run build
- 打包过程较慢,如发生异常请按如下操作(主要操作的目的就是清除缓存):
- 删除node_modules文件夹
- 删除package-lock.json
- shell中运行语句清除缓存(最好使用管理员权限):npm cache clean --force
- shell中运行语句重新安装:npm install
11.Electron结合Vue框架开发
- 利用vue脚手架初始化项目
- 在项目中安装electroncnpm i electron
- 添加electron启动配置
"main": "main.js",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"electron": "electron ."
},
- 配置main.js
const {app, BrowserWindow} = require('electron')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600
})
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
app.on('ready', () => {
createWindow()
})
- 加载Vue项目
mainWindow.loadURL('http://localhost:3000/')