250 lines
7.5 KiB
Markdown
Raw Normal View History

2023-06-29 11:55:02 +08:00
## Electron Quick Start
```
# 克隆这仓库
$ git clone https://github.com/electron/electron-quick-start
# 进入仓库
$ cd electron-quick-start
# 安装依赖库
$ npm install
# 运行应用
$ npm start
```
## 使用IPC进行GUI与原生APP进行通讯
在main.js里添加下面的代码从通道订阅消息
```
var ipc = require('ipc');
ipc.on('close-main-window', function () {
app.quit();
});
```
引入ipc模块后通过通道订阅消息就变得很简单on()方法设置订阅的通道名,定义回调函数。
渲染进程要通过通道发送消息将下面代码加入index.js
```
var ipc = require('ipc');
var closeEl = document.querySelector('.close');
closeEl.addEventListener('click', function () {
ipc.send('close-main-window');
});
```
同样我们引入ipc模块给关闭按钮的元素绑定一个click事件。当点击关闭按钮时通过「close-main-window」通道的send()方法发送消息。
## 全局快捷键
```
var globalShortcut = require('global-shortcut');
app.on('ready', function() {
... // existing code from earlier
globalShortcut.register('ctrl+shift+1', function () {
mainWindow.webContents.send('global-shortcut', 0);
});
globalShortcut.register('ctrl+shift+2', function () {
mainWindow.webContents.send('global-shortcut', 1);
});
});
```
```
ipc.on('global-shortcut', function (arg) {
var event = new MouseEvent('click');
soundButtons[arg].dispatchEvent(event);
});
```
## 保存用户配置
使用nconf模块
```
npm install --save nconf
```
```
var nconf = require('nconf').file({file: getUserHome() + '/sound-machine-config.json'});
function saveSettings(settingKey, settingValue) {
nconf.set(settingKey, settingValue);
nconf.save();
}
function readSettings(settingKey) {
nconf.load();
return nconf.get(settingKey);
}
function getUserHome() {
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
}
module.exports = {
saveSettings: saveSettings,
readSettings: readSettings
};
```
## 系统托盘
```
var remote = require('remote');
var Tray = remote.require('tray');
var Menu = remote.require('menu');
var path = require('path');
var trayIcon = null;
if (process.platform === 'darwin') {
trayIcon = new Tray(path.join(__dirname, 'img/tray-iconTemplate.png'));
}
else {
trayIcon = new Tray(path.join(__dirname, 'img/tray-icon-alt.png'));
}
var trayMenuTemplate = [
{
label: 'Sound machine',
enabled: false
},
{
label: 'Settings',
click: function () {
ipc.send('open-settings-window');
}
},
{
label: 'Quit',
click: function () {
ipc.send('close-main-window');
}
}
];
var trayMenu = Menu.buildFromTemplate(trayMenuTemplate);
trayIcon.setContextMenu(trayMenu);
```
## 打包应用
>摘自https://www.jianshu.com/p/f134878af30f
安装electron-package
```
npm install electron-package --save-dev
```
添加scrip命令 ,用于打包electron app。
```
"scripts": {
"start": "electron ."
"build": "electron-packager . hello_electron --platform=darwin --arch=x64 --ignore=node_modules/electron-*",
},
```
**electron-packager命令格式**
```
electron-packager 项目目录 app名称 --platform=平台 --arch=架构 --ignore=要忽略的目录或文件
arch
ia32 x64 armv7l all
plateform
linux win32 darwin mas all
OS X (also known as darwin)
Mac App Store (also known as mas)
```
执行命令npm run build,将得到如下结果
### electron-builder与electron-packager的区别
使用electron-builder打包应用是安装包方式而不想electron-packager打包之后直接是一个可文件夹交给所有的文件暴露出来。由electron-builder打出的包更为轻量并且可以打包出不暴露源码的setup安装程序
## 压缩源码
为避免源代码泄露,可对源码进行压缩。
**安装electron-asar**
```
npm install electron-asar --save-dev
```
**添加scrip命令 ,用于压缩源代码。**
```
"scripts": {
"start": "electron ."
"build": "electron-packager . hello_electron --platform=darwin --arch=x64 --ignore=node_modules/electron-*",
"package":"asar pack hello_electron-darwin-x64/hello_electron.app/Contents/Resources/app hello_electron-darwin-x64/hello_electron.app/Contents/Resources/app.asar"
},
```
**asar 命令格式**
asar pack <dir> <output>
执行npm run package将得到app.asar文件此时可将app文件删除。
## Electron启动node.js服务器
1.直接在index.html中启动外部的node.js服务器
2.将原生的node.js服务器代码使用module.exports = () => {}导出之后在electron的main.js中直接导入
```
app.server = require(__dirname + '/app/app')();
```
## 不迁移项目就可以打包双版本的可行方案
作者并未提供web开发的支持但是提供了非常好的web打包支持。
只要写好逻辑我们可以不用迁移项目就可以打包桌面项目和web项目。
process.env.IS_WEB是暴露的一个全局变量我们可以在渲染进程中获取项目在electron环境下返回false。否则为true。于此我们可以通过设置她的值来达到web dev的效果也可以处理不同环境的不同逻辑一些示例
![image](https://upload-images.jianshu.io/upload_images/3765249-cae045ed68c41067.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image](https://upload-images.jianshu.io/upload_images/3765249-e8f7f6ac49fdf050.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image](https://upload-images.jianshu.io/upload_images/3765249-a48751e6cf2d88e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 打开新窗口的“最佳”做法
1.使用webview allowpopups变量控制是否拦截新弹出的窗口
下面的例子是webview允许.open/.showModalDialog/.showModelessDialog的例子
electron的index.html:重点是参数allowpopups
```
<webview id="foo" src="https://newsn.net/test.html" allowpopups style="width:100%; height:360px;"></webview>
```
原文https://newsn.net/say/electron-webview-window-open.html
2.因为是webpack配置入口只有index.html ,所以打开新窗口,一般会再配置一个入口。其实还有一种更佳的做法。
```
>>> 主进程 定义好监听事件
ipc.on('newPage', function(e) {
const modalPath = process.env.NODE_ENV === 'development'
? 'http://localhost:9080/#/newPage'
: `file://${__dirname}/index.html#newPage`
let win = new BrowserWindow({
width: 1024,
height: 724,
webPreferences: {
webSecurity: false
}
})
win.on('close', function() {
win = null
})
win.loadURL(modalPath)
})
>>> router/index.js 定义路由
// import 你的新页面 .vue 文件
{
path: '/newPage',
name: 'newPage',
component: newPage,
}
》》》配置完成 任意进程调用ipc.send('newPage') 完美解决
```
3.
```
document.getElementById("youtube").onclick = function(){
youtubeWindow = new BrowserWindow ({width: 1000, height:800})
youtubeWindow.loadURL("https://youtube.com/");
youtubeWindow.on("close", function(){
youtubeWindow = null;
})
}
document.getElementById("local-list").onclick = function(){
localListWindow = new BrowserWindow ({width: 1000, height:800})
localListWindow.loadURL(`file://${__dirname}/local-list.html`);
localListWindow.on("close", function(){
localListWindow = null;
})
}
```