Electron
如果你可以建一个网站,你就可以建一个桌面应用程序。 Electron 是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架,它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可。
一、介绍
- Web 技术
Electron 基于 Chromium 和 Node.js, 让你可以使用 HTML, CSS 和 JavaScript 构建应用。 - 开源
Electron 是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目。 - 跨平台
Electron 兼容 Mac, Windows 和 Linux, 它构建的应用可在这三个操作系统上面运行。
二、入门
- Electron的API
Electron API - Electron Fiddle
Electron Fiddle 最简单的 Electron 入门方式。Electron Fiddle 让您可以创建和进行小型 Electron 实验。它会在打开后用一个快速启动模板迎接你 - 更改一些东西,选择你想要用以运行它的 Electron 版本,随意玩耍。然后,将您的 Fiddle 保存为一个 GitHub Gist 或保存到一个本地文件夹。一旦将其推送到 GitHub ,任何人都可以通过仅仅在地址栏中输入它来快速尝试您的 Fiddle 。
- Electron Forge
Electron ForgeThe command line interface for ambitious Electron applications
npm install -g electron-forge # create a new project electron-forge init my-new-project cd my-new-project electron-forge start
- 快速启动
electron-quick-start# 克隆示例项目的仓库 $ git clone https://github.com/electron/electron-quick-start # 进入这个仓库 $ cd electron-quick-start # 安装依赖并运行 $ npm install && npm start
- Electron-vue
Electron-vue该项目的目的,是为了要避免使用 vue 手动建立起 electron 应用程序。electron-vue 充分利用 vue-cli 作为脚手架工具,加上拥有 vue-loader 的 webpack、electron-packager 或是 electron-builder,以及一些最常用的插件,如vue-router、vuex 等等。
三、项目实战
1、electron-quick-start
- clone 之后 npm i 或者 yarn
- npm start 或者 electron .
- 代码
//主进程
const {app, BrowserWindow} = require('electron') //引入
let mainWindow //定义窗口的变量名
function createWindow () { //创建窗口函数
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true //是否完整的支持 node. 默认值为true. (有坑)
}
})
mainWindow.loadFile('index.html') //加载页面,可以是本地页面,也可以是网页链接
//mainWindow.loadURL('https://www.baidu.com');
mainWindow.on('closed', function () { //关闭时释放变量
mainWindow = null
})
}
app.on('ready', createWindow) //app ready事件
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
if (mainWindow === null) createWindow()
})
2、electron-vue
- vue init simulatedgreg/electron-vue my-project
- yarn
- yarn run dev
3、pddcjdz
入口文件 main.js(主进程)
mainWindow = new BrowserWindow({
width: 1300,
height: 800,
webPreferences: {
//是否完整的支持 node. 默认值为true 嵌入页面的话某些情况 需要关闭nodeIntegeration来兼容web资源的依赖加载。
nodeIntegration: false,
//当设置为 false, 它将禁用同源策略 (通常用来测试网站), 如果此选项不是由开发者设置的
webSecurity: false,
//允许一个 https 页面运行 http url 里的资源,包括 JavaScript, CSS 或 plugins.
allowRunningInsecureContent: true,
//在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。
preload: path.resolve(path.join(__dirname, './src/preload.js'))
}
})
入口中引入的脚本文件 preload.js
const electron = require('electron') //引入electron
const request = require('superagent'); //引入superagent
// DOM变异事件 https://developer.mozilla.org/zh-CN/docs/Web/Events#DOM%E5%8F%98%E5%BC%82%E4%BA%8B%E4%BB%B6
document.addEventListener('DOMNodeInserted', (event) => {
window.cjdz = {
request, //把 爬虫 request 和 electron暴露出去。
electron,
version: 1.0
}
});
//如果 nodeIntegration 值为true的话,是可以不用把electron暴露出去的,后面在页面中可以直接 使用 require('electron')来获取electron,但是为true的话代表使用electron集成的node,会和其他的一些地方有冲突; 如果为false的话,就需要把electron暴露出去,通过 window.把它找出来。
4、开发
一个electron项目只要一个主进程(main.js)
可以有多个渲染进程
electron使用Chromium来展示web页面,每个页面运行在自己的渲染进程中。
正常项目开发即可。
四、打包
1、electron-packager
electron-packager
2、electron-builder
A complete solution to package and build a ready for distribution Electron, Proton Native or Muon app for macOS, Windows and Linux with “auto update” support out of the box.
一个完整的解决方案,可以为macOS,Windows和Linux打包并构建一个可供分发的 Electron,Proton Native 或Muon应用程序,并提供开箱即用的“自动更新”支持。
electron-builder比electron-packager有更丰富的的功能,支持更多的平台,同时也支持了自动更新。除了这几点之外,由electron-builder打出的包更为轻量,并且可以打包出不暴露源码的setup安装程序。
electron-builder
electron-builder(中文)
打包一般 是:–mac(Mac)、–x64(window64)、–ia32(window32),Linux一般比较少:–linux;
"build": {
"productName": "my-project", //打包名
"appId": "org.simulatedgreg.electron-vue", //appID
"directories": {
"output": "build" //输出目录
},
"files": [ //打包文件目录
"dist/electron*"
],
"dmg": { //Mac配置 macOS DMG选项
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"mac": { //与构建macOS目标的方式相关的选项。
"icon": "build/icons/icon.icns" //Mac图标
},
"win": { //与构建Windows目标的方式相关的选项。
"icon": "build/icons/icon.ico" //windows图标
},
"linux": { //与构建linux目标的方式相关的选项。
"icon": "build/icons" //Linux图标
}
}
打包scripts
"scripts": {
"start": "electron .",
"pack": "electron-builder --dir",
"mac": "electron-builder --mac",
"win64": "electron-builder --win --x64",
"win32": "electron-builder --win --ia32"
},
yarn / npm run mac //会生成.dmg文件
yarn / npm run win64 //生成.exe文件
yarn / npm run win32 //生成.exe文件
注意:
win64和win32 生成.exe文件是同一个文件源,所以要打包之后标注一下然后在打包另一个系统。
electron-builder的使用
electron-builder的用法
Building(构建参数):
Command Line Interface (CLI)
参数 | 平台 | 类型/参考 |
---|---|---|
–mac, -m, -o, --macos | Build for macOS | array |
–linux, -l | Build for Linux | array |
–win, -w, --windows | Build for Windows | array |
–x64 | Build for x64 (64位安装包) | boolean |
–ia32 | Build for ia32(32位安装包) | boolean |
–armv7l | Build for armv7l | boolean |
–arm64 | Build for arm64 | boolean |
–dir | Build unpacked dir. Useful to test | boolean |
–prepackaged, --pd | 预打包应用程序的路径 | 以可分发的格式打包 |
–projectDir, --project | 项目目录的路径 | 默认为当前工作目录 |
–config, -c | 配置文件路径 | 默认为electron-builder.yml |
发布配置
Publish
图标生成
window和Mac图标生成
其他需求
1、点击关闭弹框确认
在主进程中对 mainWindow 进行 close事件监听,不是closed。
引用electron的 dialog
const {dialog} = require('electron');
mainWindow.on('close', (e) => {
e.preventDefault(); //阻止事件默认行为
let message = '退出后,如需使用需重新登录,请确认是否退出?';
//let message = copyTaskFlag ? '退出后,正在抓取的商品将无法继续抓取,请确认是否最小化?' : '退出后,如需使用需重新登录,请确认是否退出?'
dialog.showMessageBox({ //引用dialog
type: 'info',
title: '退出拼多多超级店长',
defaultId: 0,
message: message,
buttons: ['最小化','直接退出']
},(index)=>{
if(index===0){ //对应 buttons 数组的下标
e.preventDefault();
mainWindow.minimize(); //最小化
} else {
mainWindow = null;
app.exit(); //退出应用 立即退出程序
//app.quit(); //退出应用 尝试关闭所有窗口
}
})
});
两种退出:exit()和quit()
- exit:
直接退出整个应用 - quit:
不会直接退出应用,是关掉客户端会留在任务栏里面。
在mianWindow的close事件用这个的话,会弹出两次弹框。如果需要这种退出的话需要单独写 flag 处理一下。
2、主进程与渲染进程通信
ipcMain
ipcRenderer
ipcMain:在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息。 从渲染器进程发送的消息将被发送到该模块。
ipcRenderer:可以使用它提供的一些方法从渲染进程 (web 页面) 发送同步或异步的消息到主进程。 也可以接收主进程回复的消息。
简单实例:
Q:点击关闭按钮的时候,在渲染进程中有正在复制的时候点击关闭按钮展示一段话,没有正在复制的时候展示另一段话。
主进程:
const {ipcMain} = require('electron');
let copyTaskFlag = false; //定义一个变量 flag
ipcMain.on('copyTask-message', (event, arg) => { //监听渲染进程事件 on 监听的 事件名要和 渲染进程的事件名一致。
copyTaskFlag = arg; //arg 为渲染进程事件传过来的值
});
渲染进程:
const { ipcRenderer } = require('electron') //渲染进程中引入
ipcRenderer.send('copyTask-message', options); //send
3、客户端右键
一个新的客户端右键是没有任何东西的,需要自定义的。
//右键菜单:1 调用 electron的 menu 中的配置 https://electronjs.org/docs/api/menu-item
let electron = require('electron');
const remote = require('electron').remote;
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;
var menu = new Menu();
menu.append(new MenuItem({ label: '复制', selector: "copy:" ,role: "copy:" }));
menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: '剪切', selector: "cut:", role: "cut:"}));
menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: '粘贴', selector: "paste:", role: "paste:"}));
window.addEventListener('contextmenu', function (e) {
e.preventDefault();
menu.popup(remote.getCurrentWindow());
}, false);
//右键菜单:2 使用document的方法。
let electron = require('electron');
const remote = electron.remote;
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;
let menu = new Menu();
menu.append(new MenuItem({ label: '复制', click: function() {
document.execCommand("copy", "false", null);
}}));
menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: '黏贴', click: function() {
document.execCommand("paste", "false", null);
}}));
menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: '刷新', click: function() {
location.reload();
}}));
window.addEventListener('contextmenu', function (e) {
e.preventDefault();
menu.popup(remote.getCurrentWindow());
}, false);
4、remote 模块
remote 模块提供了一种在渲染进程(网页)和主进程之间进行进程间通讯(IPC)的简便途径。
在Electron中, GUI 相关的模块 (如 dialog、menu 等) 仅在主进程中可用, 在渲染进程中不可用。 为了在渲染进程中使用它们, ipc 模块是向主进程发送进程间消息所必需的。 使用 remote 模块, 你可以调用 main 进程对象的方法。
在渲染进程中:
1、使用dialog
const electron = require('electron').remote;
const dialog = electron.dialog;
2、BrowserWindow
const { BrowserWindow } = require('electron').remote
let win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL('https://blog.csdn.net/guoqiankunmiss')