几乎没有结构,只需要3个文件
package.json
定义一下入口文件,启动脚本,包依赖就可以
{
"name": "electron-demo",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"devDependencies": {
"electron": "^8.0.0"
}
}
main.js
// 通过 require electron 来控制程序
const { app, BrowserWindow } = require('electron')
// app加载完毕
app.on('ready', () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// 加载 html 页面
mainWindow.loadFile('index.html')
// 打开控制台
mainWindow.webContents.openDevTools()
})
// macOS 的一些设置
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
index.html
这种结构可以和任何框架(vue,ng)或普通页面结合构建桌面应用程序
基于 Chromium
的多进程架构引擎,Electron
采用了类似的结构,一个主进程(相当于浏览器)对应多个渲染引擎(相当于多个标签)
例子中运行的main.js
称为主进程,创建的 BrowserWindow
实例称为渲染进程
通过 require('electron')
来使用 Electron
提供的 API
,有些 API
仅供渲染进程使用或仅供主进程使用,也有一些 API
两类进程都可使用
在渲染进程中创建BrowserWindow实例
BrowserWindow
对象只能在主进程中使用,为了在渲染进程中也可以创建新实例,可以与主进程通信来执行任务
Electron通过 remote
模块暴露了一些在主进程中才能使用的 API
// 渲染进程无法通过此方式使用 BrowserWindow 对象
// const { BrowserWindow } = require('electron')
const { remote } = require('electron')
// 使用 remote 暴露的 API
const { BrowserWindow } = remote
new BrowserWindow({
/* ... */
})
使用node.js API
在 Electron
可以使用所有的 node.js
API,可以和底层交互了哇
譬如 fs
const fs = require("fs");
document.getElementById("save").onclick = () => {
let writerStream = fs.createWriteStream("test.txt"); //Write输入流
writerStream.write("hello","UTF-8");
writerStream.on("finish",function(chunk){
/* ... */
})
writerStream.on("err",function(err){
console.log(err.stack);
})
}
渲染进程可以使用h5新增的 HTML5 Notification API
,主进程可以使用 Electron 的 Notifications
模块,两者体验类似,但仍有细微差异
主进程
const { Notification } = require('electron')
// 创建一条通知
let notification = new Notification({
title: '标题',
body: '正文'
})
// 事件处理
// show 事件
notification.on('show', () => {
console.log("通知显示")
})
// close 事件
// 这个事件不能保证在所有情况下都会触发,譬如使用 close 方法或单击导致的关闭不会触发
notification.on('close', () => {
console.log("通知关闭")
})
// click 事件
notification.on('click', () => {
console.log("通知被单击")
})
// 当前系统是否支持桌面通知
if(Notification.isSupported()){
notification.show() // 立即显示
setTimeout(() => {
notification.close() // 延时关闭
}, 5000)
}
详细的通知参数和事件见 官方API文档
渲染进程
注:此 API 属 h5 新特性,不仅仅针对 Electron
// 浏览器是否支持此特性
if(! window.Notification){
console.log("浏览器不支持 Notification 特性")
}
// 是否有通知权限
else if(Notification.permission === 'granted'){
let notification = new Notification('标题', {
body: '正文',
icon: 'favicon.ico'
})
// new 后自动弹出,无需手动显示
setTimeout(() => {
notification.close() // 手动关闭
}, 2000)
// 事件处理
// click 事件
notification.onclick = () => {
console.log("通知被单击")
}
// show 事件
notification.onshow = () => {
console.log("通知显示")
}
// error 事件
notification.onerror = () => {
console.log("错误")
}
// close 事件
// 和主进程 Electron 的 Notification 对象相比,这个事件保证在多数情况下都会触发
notification.onclose = () => {
console.log("通知被关闭")
}
}
// 请求权限
else if (Notification.permission !== 'denied') {
Notification.requestPermission(permission => {
// 如果用户同意,就可以向他们发送通知
if (permission === "granted") {
let notification = new Notification("Hi there!");
}
});
}
WIN10渲染进程通知被拦截无法显示
开发环境下,通常默认通知可以显示,手动禁止后,因为通知管理无对应应用程序,所以无法恢复禁止,需要在主进程加入:
app.setAppUserModelId(process.execPath)
然后将 node_modules\electron\dist\electron.exe
固定到开始屏幕,即可恢复显示,若再次禁止,可以更换文件夹再次尝试
win10.v1909 测试只需要加入 app.set...
语句即可恢复显示
官方DOC
安装
npm install electron-packager --save-dev
打包命令
electron-packager --platform= --arch= [--out= --icon= optional flags...]
arg | details |
---|---|
sourcedir | 项目路径 |
appname | 应用名 |
platform | 平台 |
arch | 架构 |
outdir | 输出路径 |
icon | 图标 |
可以添加到脚本中方便打包,例子:
"packager": "electron-packager ./ testApp --platform=win32 --arch=ia32 --out=./outApp --icon=./favicon.ico"
解决资源被墙无法打包
可以使用淘宝仓库
npm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/
或者在 package.json 配置
"build": {
"electronDownload": {
"mirror": "https://npm.taobao.org/mirrors/electron/"
}
}
使用时发现它是去 源/vx.x.x/
下载,淘宝镜像格式是 源/x.x.x/
,所以只能手动下载它需要的资源,然后放在自己的服务器(或本地?),设为自己的源再打包
譬如使用 v8.0.0 版本的 Electron,按上面的脚本,会下载
两个文件,将这两个文件部署到自己的仓库就可以进行打包了
electron-packager 仅在首次打包时下载资源,以后打包断网什么的都随意
安装
npm install electron-builder --save-dev
打包命令
"scripts": {
"electron-builder": "electron-builder --win --x64", // 生成绿色版 + 安装包 + 绿色版压缩包
"electron-builder-dir": "electron-builder --dir --win --x64" // 仅生成绿色版
},
"build": {
"appId": "com.demo.app",
"mac": {
"target": ["dmg","zip"]
},
"win": {
"target": ["nsis","zip"]
},
"directories": {
"output": "builder" // 指定打包内容存放路径
},
"files": [ // 指定要打包的资源
"dist/**/*", // html 项目资源
"main.js" // electron 入口文件
]
}
解决资源被墙无法打包
首次打包会下载必要的资源,资源是国外源,很容易超时导致失败,需手动下载(慢慢等总会下载完的)或下载,得到需要的资源
C:\Users\username\AppData\Local\electron-builder\Cache
如果只需要打包为绿色版就不需要下载 nsis 和 nsis-resources 了
修改 package.json
的 start
脚本
"start": "electron ."
↓
"start": "chcp 65001 && electron ."