Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用
使用须知
Electron 需要 node 的支持,文中举例,默认 yarn 和 node 是已经安装了,如果没有安装,请先安装后;
项目开启
# 创建文件夹并进入文件夹
mkdir demo && cd demo
# 初始化项目
yarn init -y
# 安装 electron
yarn add --dev electron
添加配置命令
...
"main": "main.js", //入口文件
"scripts": {
"start": "electron ." //启动命令
},
添加入口文件
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
<p id="info"></p>
<!-- 执行脚本,可以添加其他的执行脚本 -->
<script src="./renderer.js"></script>
</body>
</html>
const { app, BrowserWindow } = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
// 只有在app模块的ready事件被激发后才能创建浏览器窗口
app.whenReady().then(() => {
createWindow() //通过调用createWindow
app.on('activate', () => {
// 在macOS上,当单击图标,并没有其他窗口打开
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// 监听关闭窗口,在所有窗口关闭后,退出
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
在执行 yarn start 后,可以看到一个应用窗口被打开。
添加预加载脚本
为了将 Electron 的不同类型的进程桥接在一起,我们需要使用被称为 预加载 的特殊脚本
const { contextBridge } = require('electron');
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
});
** 注意:如果发现报错提示contextBridge API can only **
// ...
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// __dirname 字符串指向当前正在执行脚本的路径 (在本例中,它指向你的项目的根文件夹)
// path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
// ...
<p id="info"></p>
<script src="./renderer.js"></script>
</body>
</html>
const information = document.getElementById('info');
information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`;
界面配置
界面设置,可以通过关闭所有菜单,然后自定义菜单去管理,也可以简单的通过预设菜单去管理
const { app, BrowserWindow ,Menu} = require('electron')
// ...
const template=[] //菜单为空
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
const win = new BrowserWindow({
// ...
// frame: false, //关闭所有菜单
// resizable: false, //界面缩放
// titleBarStyle: 'hidden', //隐藏边框
})
// 穿透窗口:忽略所有点击事件
win.setIgnoreMouseEvents(true)
调试模式
打开调试控制台 模式:right
left
bottom
detach
; 关闭控制台 closeDevTools()
const { app, BrowserWindow } = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
+ win.webContents.openDevTools({mode:'detach'})
win.loadFile('index.html')
}
// ...
优雅显示
- ready-to-show
在项目第一次渲染的时候,可能会出现闪烁,可以通过设置 show:false
,在特定的时候显示出来
// ...
const win = new BrowserWindow({
// ...
show: false, //关闭显示
})
// 第一次完成绘制时,如果窗口还没有被显示,渲染进程会发出 ready-to-show 事件
win.once('ready-to-show', () => {
win.show()
})
```
- backgroundColor
当项目过于复杂的时候,ready-to-show事件可能会比较缓慢,可以不使用 `ready-to-show` 简单的设置背景颜色就好了,
使用了 `ready-to-show` 也可以使用背景色,使应用更贴近原生
```js main.js
// ...
const win = new BrowserWindow({
// ...
backgroundColor: '#fff', //应用背景色
})
自动更新
update.electronjs.org
Electron 官方在 https://update.electronjs.org 上为开源应用程序提供了免费的自动更新服务。 使用它有以下几点要求:
- 你的应用在 macOS 或 Windows 上运行
- 你的应用有一个公开的 GitHub 仓库
- 应用程序需要发布到 GitHub releases 中
- 应用程序需要完成 签名
Electron-forge打包
# 安装 Electron Forge 打包脚手架. 并通过import自动化设置
yarn add --dev @electron-forge/cli
npx electron-forge import
# 自动配置后执行
# 打包命令
npm run package
# 配置分发资源 exe执行软件资产
npm run make
Electron-forge 配置
如果没有在 package.json
文件中设置config.forge,Forge将尝试项目根目录中找到 forge.config.js
文件.
可以在 package.json
中配置,也可以通过 forge.config.js
配置
- package.json
{
"name": "my-app",
"version": "0.0.1",
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-zip"
}
]
}
}
}
- forge.config.js
module.exports = {
packagerConfig: {},
makers: [
{
name: '@electron-forge/maker-zip'
}
]
}
配置图标
准备图标,MacOS:icns(512px x 512px) Linux:png(512px x 512px) Windows:ico(256px x 256px)
images/
├── icon.png
├── icon@2x.png
└── icon@3x.png
window 平台配置
module.exports = {
// ...
config: {
forge: {
packagerConfig: {
icon: '/path/to/icon'
}
}
}
}
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
// ...
icon: '/path/to/icon.png'
})
问题
安装时间太长
国内的网络问题及安装地址的指向问题,导致国内安装的很慢
nrm use taobao
npm config edit
registry=https://registry.npmmirror.com/
// 在 registry 下添加指向地址
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
资源被锁定或太忙 EBUSY: resource busy or locked
项目在运行导致安装失败,关闭执行中的项目在安装;
打包时候报错 Making a squirrel distributable for win32/x64
package.json 缺少必要字段 authors
description
{
//...
"authors": "xianbin", //作者
"description":"a electron demo", //描述
}
报错 contextBridge API can only be used when contextIsolation is enabled
需要启动 contextIsolation 才能对 contextIsolation 进行编程,从Electron12.0开始,会默认启用contextIsolation
// ...
webPreferences: {
contextIsolation: true,
// __dirname 字符串指向当前正在执行脚本的路径 (在本例中,它指向你的项目的根文件夹)
preload: path.join(__dirname, 'preload.js')
}
报错 require is not defined
需要在启动时候设置 contextIsolation 为 false
// ...
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
// __dirname 字符串指向当前正在执行脚本的路径 (在本例中,它指向你的项目的根文件夹)
preload: path.join(__dirname, 'preload.js')
}
警告 DevTools failed to load source map
打开控制台设置,将 Preferences => sources 中的 Enable tab moves focus 和 Enable CSS source maps 关闭。
警告 Electron Security Warning (Insecure Content-Security-Policy)
有两种解决方式,
1: 设置安全策略
...
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline';">
2: 屏蔽警告
// ...
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';