250 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
## 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的效果,也可以处理不同环境的不同逻辑,一些示例:
 | 
						||

 | 
						||

 | 
						||

 | 
						||
 | 
						||
## 打开新窗口的“最佳”做法
 | 
						||
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;
 | 
						||
        })
 | 
						||
    }
 | 
						||
``` |