主进程与渲染进程
- Electron 运行
package.json
的main
脚本的进程被称为主进程。 - 每个 Electron 中的 web 页面运行在它的叫渲染进程的进程中。
区别
主进程会通过BrowserWindow
创建页面,每个BrowserWindow
都有自己的渲染进程运行页面。
主进程管理所有web页面和他们对应的渲染进程,每一个渲染进程都是独立。
不允许操作GUI的原生API,如果需要的话,必须通过主进程来进行通讯。
使用 electron 的 API
无论时主进程还是渲染进程,都是通过
const electron = require('electron')
有点区别在于,有些API只能在相应的进程使用,例如:BrowserWindow
只能在主进程使用。
进程之间的通讯
// In the 主进程 process:
const { ipcMain } = require('electron')
ipcMain.handle('perform-action', (event, ...args) => {
// 处理渲染进程的事件
})
// In the 渲染进程 process:
const { ipcRenderer } = require('electron')
ipcRenderer.invoke('perform-action', ...args)
例子1:在渲染进程使用主进程的模块
remote
是主进程与渲染进程的通讯的一个简单的方法。
官方其实不推荐渲染进程调用主进程的方法,主要是安全与性能的问题。
如果需要使用到remote
的对象的话,需要在主线程把这个允许配置打开。
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration : true,
enableRemoteModule:true
},
});
然后使用remote
里的dialog
来创建窗口
// event.js
const {dialog} = require('electron').remote
console.log('remote',require('electron'))
function onClick_OpenFile() {
const label = document.getElementById('label');
label.innerText= dialog.showOpenDialogSync({properties: ['openFile']})
}
function onClick_CustomOpenFile() {
const label = document.getElementById('label');
var options = {};
options.title = '打开文件';
options.message = '打开我的文件';
options.buttonLabel = '选择';
// Mac OSX 默认目录是桌面
options.defaultPath = '.';
options.properties = ['openFile'];
label.innerText= dialog.showOpenDialog(options)
}
function onClick_FileType(){
const label = document.getElementById('label');
var options = {};
options.title = '打开文件';
options.buttonLabel = '选择';
// Mac OSX 默认目录是桌面
options.defaultPath = '.';
options.properties = ['openFile'];
options.filters = [
{name: '图像文件', extensions: ['jpg', 'png', 'gif']},
{name: '视频文件', extensions: ['mkv', 'avi', 'mp4']},
{name: '音频文件', extensions: ['mp3','wav']},
{name: '所有文件', extensions: ['*']}
]
label.innerText= dialog.showOpenDialog(options)
}
function onClick_OpenAndCreateDirectory() {
const label = document.getElementById('label');
var options = {};
options.title = '打开目录';
// createDirectory仅用于Mac OS 系统
options.properties = ['openDirectory','createDirectory'];
label.innerText= dialog.showOpenDialog(options)
}
function onClick_MultiSelection() {
const label = document.getElementById('label');
var options = {};
options.title = '选择多个文件和目录';
options.message = '选择多个文件和目录';
options.properties = ['openFile','multiSelections'];
if (process.platform === 'darwin') {
options.properties.push('openDirectory');
}
label.innerText= dialog.showOpenDialog(options)
}
function onClick_Callback() {
const label = document.getElementById('label');
var options = {};
options.title = '选择多个文件和目录';
options.message = '选择多个文件和目录';
options.properties = ['openFile','multiSelections'];
if (process.platform === 'darwin') {
options.properties.push('openDirectory');
}
dialog.showOpenDialog(options,(filePaths) =>{
for(var i = 0; i < filePaths.length;i++) {
label.innerText += filePaths[i] + '\r\n';
}
});
}
// main.js
const { app, BrowserWindow } = require('electron')
console.log('electron',require('electron'))
function createWindow() {
// 创建浏览器窗口
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration : true,
enableRemoteModule:true
},
});
// 然后加载应用的 index.html
win.loadFile('index.html');
// 打开控制台
win.webContents.openDevTools();
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
console.log('窗口被关闭');
//非 Mac OS X 平台,直接调用 app.quit() 方法退出程序
if (process.platform !== 'darwin') {
app.quit();
}
});
// index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<script src='event.js'></script>
</head>
<body>
<button onclick="onClick_OpenFile()">打开文件对话框</button>
<button onclick="onClick_CustomOpenFile()">定制打开对话框</button>
<button onclick="onClick_FileType()">指定文件类型</button>
<button onclick="onClick_OpenAndCreateDirectory()">打开和创建目录</button>
<button onclick="onClick_MultiSelection()">选择多个文件或目录</button>
<button onclick="onClick_Callback()">通过回调函数返回选择的文件和目录</button>
<label id="label" style="font-size: large"></label>
</body>
</html>
使用 nodejs 的 api
主进程使用直接引入即可,但是如果需要在渲染进程也使用require
的话,需要在主进程配置允许渲染进程获取。
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// 设置为TRUE
nodeIntegration : true,
},
});
除了nodejs 的原生API,我们也可以引入npm下载的nodejs模块
这里一共提供了多种的引入 的方法,大家可以阅读官方的文档
这里主要例举我们普通开发者使用的方法:
-
用
electron-rebuild
包重建这些模块以适配 Electronnpm install --save-dev electron-rebuild # 每次运行"npm install"后,也运行这条命令 ./node_modules/.bin/electron-rebuild # 在windows下如果上述命令遇到了问题,尝试这个: .\node_modules\.bin\electron-rebuild.cmd