介绍:Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。通过将Chromium和Node.js嵌入到其二进制文件中,Electron 允许您维护一个 JavaScript 代码库并创建可在 Windows、macOS 和 Linux 上运行的跨平台应用程序
一.基础文档
1.新建项目
1).# 安装 vue-cli 和 脚手架样板代码
npm install -g @vue/cli
vue init simulatedgreg/electron-vue my-project
各种选项可以根据实际需要选择
2).打开编译器终端,cd进项目文件夹
安装依赖npm install
并运行程序 npm run dev
注:运行程序可能会报错Error: Electron failed to install correctly, please delete node_modules/electron and try installing again,提示删除electron重新下载,可能会不好使,应该是npm的问题,可以用cnpm淘宝镜像安装electron来解决问题。
1.首先删除electron
2.安装配置cnpm
npm install -g cnpm --registry=registry.npm.taobao.org
3.使用cnpm安装electron,用法与npm类似。
cnpm install --save electron
4.确认是否安装成功
electron -v
安装成功后再次npm run dev 程序就跑起来了
electron中Unable to install vue-devtools的解决方法
由于网络的问题,electron运行的时候加载vue-devtools失败。 Unable to install vue-devtools 。从日志里看retry了四次都timeout了。
先 npm install vue-devtools --save-dev
然后 把ready事件里面注释掉5行,再加上一行手动加载的。
最终src/main/index.dev.js里面修改后的内容如下(所有内容):
/* eslint-disable */
// Install electron-debug with devtron
require('electron-debug')({ showDevTools: true })
import { BrowserWindow } from 'electron';
// Install vue-devtools
require('electron').app.on('ready', () => {
let installExtension = require('electron-devtools-installer')
// installExtension.default(installExtension.VUEJS_DEVTOOLS)
// .then(() => {})
// .catch(err => {
// console.log('Unable to install vue-devtools: \n', err)
// })
BrowserWindow.addDevToolsExtension('node_modules/vue-devtools/vender') //手动加载vue-devtools,前提是 npm install vue-devtools --save-dev
})
// Require main process to boot app
require('./index')
Npm run dev 后报错 [8492:0407/121603.977907:ERROR:CONSOLE(7830)] "Extension server error: Object not found: " , source : chrome-devtools://devtools/bundled/shell.js (7830) 的解决方法
可以在index.dev.js文件中
- require('electron-debug')({ showDevTools: true });
- require('electron-debug')();
报错 Starting inspector on 127.0.0.1:5858 failed: address already in use
端口被占用
找到.electron-vue文件夹下dev-runner.js文件,修改如下
var args = [
// '--inspect=5858',
'--inspect=58588',
path.join(__dirname, '../dist/electron/main.js')
]
2. 项目目录
单一的 package.json 设置
electron-packager 和 electron-builder 现在完全支持单一的 package.json 设置。
dependencies
这些依赖项将会被包含在你最终产品的应用程序中。所以,如果你的应用程序需要某个模块才能运行,那么请在此安装!
devDependencies
这些依赖项不会被包含在你最终产品的应用程序中。在这里,你可以安装专门用于开发的模块,如构建脚本、webpack 加载器等等。
安装原生 NPM 模块
我们需要确保我们本地的 npm 模块是针对 electron 来构建的。为了做到这一点,我们可以使用 electron-rebuild,但是为了使事情变得更简单,我们强烈建议使用electron-builder 作为你的构建工具,因为它会为你处理很多任务。
关于 main 进程
在开发过程中,你可能会注意到 src/main/index.dev.js。该文件专门用于开发以及安装开发工具。原则上,该文件不应该被修改,但是可以被用来扩展你的开发需求。在构建的过程中,webpack 将介入其中并创建一个的捆绑,以 src/main/index.js 作为该捆绑的入口文件。
文件树
注意: 某些文件或文件夹可能会根据在 vue-cli 脚手架中所选设置的不同而有所不同。
my-project
├─ .electron-vue
│ └─ <build/development>.js files
├─ build
│ └─ icons/
├─ dist
│ ├─ electron/
│ └─ web/
├─ node_modules/
├─ src
│ ├─ main
│ │ ├─ index.dev.js
│ │ └─ index.js
│ ├─ renderer
│ │ ├─ components/
│ │ ├─ router/
│ │ ├─ store/
│ │ ├─ App.vue
│ │ └─ main.js
│ └─ index.ejs
├─ static/
├─ test
│ ├─ e2e
│ │ ├─ specs/
│ │ ├─ index.js
│ │ └─ utils.js
│ ├─ unit
│ │ ├─ specs/
│ │ ├─ index.js
│ │ └─ karma.config.js
│ └─ .eslintrc
├─ .babelrc
├─ .eslintignore
├─ .eslintrc.js
├─ .gitignore
├─ package.json
└─ README.md
产品构建****
app.asar
├─ dist
│ └─ electron
│ ├─ static/
│ ├─ index.html
│ ├─ main.js
│ └─ renderer.js
├─ node_modules/
└─ package.json
可以说,几乎所有的东西都在最终的产品构建中被删除。在分发 electron 应用程序时,这几乎是强制性的,因为你不希望用户下载拥有庞大文件的臃肿的软件。
3.项目配置单
electron的相关配置和vue共用一个文件vue.config.js,注意,这个文件如果不存在,需要自己新建一个。下面是配置所在位置
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// 用户自己的构建配置放在这里
// 在这里的配置将会和默认配置合并,然后传递给electron-builder
}
}
}
}
通用配置
下面的配置是通用的,对所有的平台打包产物都有用,更多详细信息可以查看 Electron Builder Configuration Options
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// 在这里的配置将会和默认配置合并,然后传递给electron-builder
appId: 'com.example.vue-electron', // 项目唯一标识
productName: 'Vue-Electron', // 打包产物的前缀
copyright: 'Copyright © year {}引用package.json里面配置项,配置项不存在会报错
directories: {
output: 'dist' // 打包产物的位置
}
}
}
}
}
Mac平台的配置
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// 在这里的配置将会和默认配置合并,然后传递给electron-builder
appId: 'com.example.vue-electron', // 项目唯一标识
productName: 'Vue-Electron', // 打包产物的前缀
copyright: 'Copyright © year {}引用package.json里面配置项,配置项不存在会报错
directories: {
output: 'dist' // 打包产物的位置
},
// ------- Mac 相关配置
mac: {
icon: 'build/icons/icon.icns', // 应用图标
category: 'public.app-category.utilities', // 应用类型
target: ['dmg'] // 打包的目标类型(默认是dmg和zip),支持很多类型,具体看文档
}
}
}
}
}
图标需要Mac平台特点的图标文件,category是应用的类型,target为打包产物类型
Win平台的配置
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// 在这里的配置将会和默认配置合并,然后传递给electron-builder
appId: 'com.example.vue-electron', // 项目唯一标识
productName: 'Vue-Electron', // 打包产物的前缀
copyright: 'Copyright © year {}引用package.json里面配置项,配置项不存在会报错
directories: {
output: 'dist' // 打包产物的位置
}
// ------- windows 相关配置
win: {
icon: 'build/icons/icon.ico', // 应用图标
target: ['nsis'] // 打包的目标类型,支持很多类型
},
nsis: {
"oneClick": false,
"perMachine": true,
"allowToChangeInstallationDirectory": true // 允许修改安装目录
}
}
}
}
}
nsis配置可参考www.electron.build/configurati…
Linux平台的配置
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// 在这里的配置将会和默认配置合并,然后传递给electron-builder
appId: 'com.example.vue-electron', // 项目唯一标识
productName: 'Vue-Electron', // 打包产物的前缀
copyright: 'Copyright © year {}引用package.json里面配置项,配置项不存在会报错
directories: {
output: 'dist' // 打包产物的位置
}
// ------- linux 相关配置
linux: {
icon: "build/icons", // 包含各种尺寸图标的文件夹
target: [
"AppImage",
"deb",
"rpm"
],
category: "Utility",
}
}
}
}
}****
linux相关配置见www.electron.build/configurati…
图标的生成
项目添加electron-icon-builder依赖
npm i electron-icon-builder -D
然后再package.json里面scripts中添加如下脚本:
"electron:icon": "electron-icon-builder --input=./static/icon.png --output=build --flatten"
需要将名字为icon.png,大小为256*256的原始图标文件放置在static文件夹内,当然static也可以是其他目录然后执行如下命令,就可以生成所有平台的图标了.
npm run electron:icon
BrowserWindow的常用配置
文件位置src/main/index.js
function createWindow() {
mainWindow = new BrowserWindow({ //创建接口
width: Integer -窗口宽度,单位像素. 默认是 800
height: Integer - 窗口高度,单位像素. 默认是 600.
x: Integer - 窗口相对于屏幕的左偏移位置.默认居中.
y: Integer - 窗口相对于屏幕的顶部偏移位置.默认居中.
useContentSize:Boolean - width和 height使用web网页size, 这意味着实际窗口的size应该包括窗口框架的size,稍微会大一点,默认为 false
center:Boolean - 窗口屏幕居中.
minWidth:Integer - 窗口最小宽度,默认为 0
minHeight:Integer - 窗口最小高度,默认为 0
maxWidth:Integer - 窗口最大宽度,默认无限制.
maxHeight:Integer - 窗口最大高度,默认无限制.
resizable:Boolean - 是否可以改变窗口size,默认为 true
movable:Boolean - 窗口是否可以拖动. 在 Linux 上无效. 默认为 true
minimizable:Boolean - 窗口是否可以最小化. 在 Linux 上无效. 默认为 true
maximizable:Boolean - 窗口是否可以最大化. 在 Linux 上无效. 默认为 true
closable:Boolean - 窗口是否可以关闭. 在 Linux 上无效. 默认为 true
alwaysOnTop:Boolean - 窗口是否总是显示在其他窗口之前. 在 Linux 上无效. 默认为 false
fullscreen:Boolean - 窗口是否可以全屏幕. 当明确设置值为 false,全屏化按钮将会隐藏,在 macOS 将禁用. 默认 false
fullscreenable:Boolean - 在 macOS 上,全屏化按钮是否可用,默认为 true
skipTaskbar:Boolean - 是否在任务栏中显示窗口. 默认是false
kiosk:Boolean - kiosk 方式. 默认为 false
title:String - 窗口默认title. 默认 "Electron"
icon:NativeImage - 窗口图标, 如果不设置,窗口将使用可用的默认图标.
show:Boolean - 窗口创建的时候是否显示. 默认为 true
frame:Boolean - 指定 false来创建一个 Frameless Window. 默认为 true
acceptFirstMouse:Boolean - 是否允许单击web view来激活窗口 . 默认为 false
disableAutoHideCursor:Boolean - 当 typing 时是否隐藏鼠标.默认 false
autoHideMenuBar:Boolean - 除非点击 Alt,否则隐藏菜单栏.默认为 false
enableLargerThanScreen:Boolean - 是否允许改变窗口大小大于屏幕. 默认是 false
backgroundColor:String -窗口的 background color 值为十六进制,如 #66CD00(支持透明度). 默认为在 Linux 和 Windows 上为 #000(黑色) , Mac上为 #FFF(或透明).
hasShadow:Boolean - 窗口是否有阴影. 只在 macOS 上有效. 默认为 true
darkTheme:Boolean - 为窗口使用 dark 主题, 只在一些拥有 GTK+3 桌面环境上有效. 默认为 false
transparent:Boolean - 窗口 透明. 默认为 false
type:String - 窗口type, 默认普通窗口.
titleBarStyle:String - 窗口标题栏样式.
webPreferences:Object - 设置界面特性.
});
mainWindow.loadURL(winURL); //加载窗口url,来自renderer进程的页面
app.on("ready", createWindow); //app准备好时创建窗口
可根据需求设置以上属性。
二.常用api
1.主进程api
-
shell 通过url的方式对文件进行操作
-
screen 屏幕大小鼠标位置
-
clipborad 剪切板文本文件
-
crashReporter崩溃报告可以发送崩溃报告(需要外部服务支持)
-
nativeImage所有与图片有关的模块
-
ipcRender 渲染进程模块可以监听ipc信道中的事件以及接受ipc信道中的信息可用于与主进程(ipcMain)通信也可以和其他渲染进程通过webContents实例的send方法利用 id标志通信
7.desktopCapturer用来捕获桌面的声音视频,类似于录屏软件
8.remote 渲染进程想要拿到主进程的模块,例如菜单,提示框对象,只要是可枚举的就可以获取
9.webFrame 控制如何显示与渲染网页,例如网页的缩放,安全策略
10.app 控制应用的生命周期
11.BrowserWindow 创建控制浏览器窗口
12.webContents 是BrowserWindow的一个实例属性,用于渲染和控制网页
13.ipcMain 发送与接收ipc消息的一个模块(同步通信方式有坑,不要使用,在win7环境会导致页面渲染卡死)
14.dialog 可以用来打开和保存文件以及提示框功能
-
Menu 可以创建鼠标右键菜单以及应用菜单以及通知栏小图标里面的菜单
-
net 是Electron自带的一个http请求库
-
protocol 可以注册协议,例如 file
-
session 管理浏览器会话在webContents实例下可以拿到单层页面的session
-
Tray 系统托盘可以添加通知栏区域的图标可以设置右键列表和点击事件(即win右下角那部分)
-
systemPerferences可以获取当前计算机的偏好设置
-
globalShortcut可以用来定义键盘的快捷键
-
contentTracing用来跟踪收集数据的模块可以用来查看性能瓶颈
-
powerSaveBlocker阻止系统进入睡眠模式
-
powerMonitor监听电源状态更改的模块
-
autoUpdater自动更新
2 . 渲染进程api
1. Electron desktopCapturer 模块:desktopCapturer 模块可用来获取可用资源,这个资源可通过 getUserMedia 捕获得到。
2. Electron ipcRenderer 模块:ipcRenderer 模块是一个 EventEmitter 类的实例。它提供了有限的方法,可以从渲染进程向主进程发送同步或异步消息。也可以收到主进程的响应。
3. Electron remote 模块:remote 模块提供了一种在渲染进程(网页)和主进程之间进行进程间通讯(IPC)的简便途径。Electron中, 与GUI相关的模块(如 dialog, menu 等)只存在于主进程,而不在渲染进程中 。为了能从渲染进程中使用它们,需要用ipc模块来给主进程发送进程间消息。使用 remote 模块,可以调用主进程对象的方法,而无需显式地发送进程间消息,这类似于 Java 的 RMI。
4. Electron webFrame 模块:web-frame 模块允许你自定义如何渲染当前网页。
5.ipcMain和ipcRenderer :实现父子组件间的通信,ipcMain是在main进程里面使用,ipcRenderer是在renderer进程里面使用
三.调试方法
1.控制台的打开方式:f12
2.各类资源查找
Electron-vue文档:simulatedgreg.gitbooks.io/electron-vu…
Electronjs官方文档:
www.electronjs.org/zh/docs/lat…
3.页面调试
需调试位置打debugger
四.打包
1 .代码混淆
bytenode可以将你的JavaScript代码编程成V8字节码,这可以有效的保护你的源码
npm install --save bytenode
在根目录下添加一个bytenode.js的文件
文件内容:
'use strict';
const fs = require('fs');
const path = require('path');
const bytenode = require('bytenode');
const v8 = require('v8');
v8.setFlagsFromString('--no-lazy');
try {
(async function () {
try {
await bytenode.compileFile({
filename: pathName,
electron: true, // electron的项目这个参数一定要加上
compileAsModule: true
}, ${pathName}c);
// 将原来的js文件里面的内容替换成下面的内容
fs.writeFileSync(pathName, 'require("bytenode");require("./main.jsc");', 'utf8');
} catch (e) {
console.error(run_bytenode_err: ${e});
}
}());
} catch (e) {
console.error(run_bytenode_err: ${e});
}
写好脚本文件以后需要在package.json文件里面去添加脚本
"scripts": {
"build": "xxxxxxxxxxxxxxxxx", // 假设这是你的webpack打包代码的脚本
"bytenode": "node ./bytenode.js", // 添加bytenode的脚本 执行之前写好的js文件
"electron-build": "xxxxxxxxxxxxxxxxx" // 假设这是你的electron打包的脚本
"pack": "npm run pack:main && npm run pack:renderer&& npm run bytenode" ,// 在这里加上bytenode的脚本
},
出现eslint报错import
Babel的安装:
npm install -g babel-cli // -g 表示全局安装到 nodejs 下的目录
将 Babel 的转换插件安装到项目的目录中:
npm install babel-preset-es2015 --save
执行手动转换命令:
babel es6.js --out-file es5.js --presets es2015
2 .打包
采用了electron-builder来打包
全局安装electron-builder打包工具:npm install -g electron-builder@23.0.2
2、在项目根目录下的package.json文件中配置打包相关信息:
图中圈住部分是在windows下打包的配置,ia32代表生成的exe文件是32位的,因为64位电脑可运行32和64位的exe文件,所以直接打包32位就可以了,
打包后的输出文件是放到了build目录下,因为配置了
"directories": {
"output": "build"
},
然后进行npm run pack编译
最后执行
electron-builder -m //mac
electron-builder -w//windows
Mac:
Windows:
五.原生electron与electron-vue的关系
Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。通过将Chromium和Node.js嵌入到其二进制文件中,Electron 允许您维护一个 JavaScript 代码库并创建可在 Windows、macOS 和 Linux 上运行的跨平台应用程序——无需原生开发经验。
electron-vue 是一个基于 vue 来构造 electron 应用程序的样板代码,类似于vue-cli。该项目的目的,是为了要避免使用 vue 手动建立起 electron 应用程序。electron-vue 充分利用 vue-cli 作为脚手架工具,加上拥有 vue-loader 的 webpack、electron-packager 或是 electron-builder,以及一些最常用的插件,如vue-router、vuex 等等。
Electron-vue可以直接使用electron的api,可以直接在main.js中按需引入
六.项目更新
安装插件
npm install electron-updater --save
复制代码配置publish
vue.config.js文件,builder配置内添加publish,如下:
配置publish项,是为了打包后生成latest.yml文件,该文件是用于判断版本升级的。是打包过程中生成的,为避免自动升级报错,生成后禁止修改文件内容,若文件有误,需要重新打包生成。
注意,这里有个坑,如果服务器更新地址经常变动,这里的url建议不填写,在主进程获取到url后,通过api重新设置。
latest.yml文件记录了版本号、更新包的路径、包大小、日期等。
主进程代码
electron-updater插件的代码必须在主进程执行
import { autoUpdater } from 'electron-updater'
// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
function updateHandle (updateConfig) {
let message = {
error: 'update error',
checking: 'updating...',
updateAva: 'fetch new version and downloading...',
updateNotAva: 'do not to update'
}
// 设置服务器更新地址
autoUpdater.setFeedURL({
provider: 'generic',
url: updateConfig.download
})
autoUpdater.on('error', function () {
sendUpdateMessage(message.error)
})
autoUpdater.on('checking-for-update', function () {
sendUpdateMessage(message.checking)
})
// 版本检测结束,准备更新
autoUpdater.on('update-available', function (info) {
sendUpdateMessage(message.updateAva)
})
autoUpdater.on('update-not-available', function (info) {
sendUpdateMessage(message.updateNotAva)
})
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
console.log('下载进度百分比>>>', progressObj.percent)
})
// 下载完成
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
// 退出且重新安装
autoUpdater.quitAndInstall()
})
ipcMain.on('checkForUpdate', () => {
// 执行自动更新检查
autoUpdater.checkForUpdates()
})
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage (text) {
mainWindow.webContents.send('message', text)
}
}
export default updateHandle
渲染进程代码
// ####### 请保证updateHandle方法在主进程已经调用过一遍,事件监听都存在
// 检测更新
ipcRenderer.send('checkForUpdate')
读取进度条组件
主进程向渲染进程页面发送进度数据,展示当前更新进度