前提准备:
cnpm init --yes // 创建electron配置
eslint --init //错误检查
cnpm i electron --save-dev // 补全
//然后再index.html 中创建.html5 ,自动生成demo页面
调试脚本(放入.vscode/launch.json):
{
"version": "0.2.0",
"compounds": [
{
"name": "Main + renderer",
"configurations": ["Main", "Renderer"],
"stopAll": true
}
],
"configurations": [
{
"name": "Renderer",
"port": 9222,
"request": "attach",
"type": "chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Main",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": [".", "--remote-debugging-port=9222"],
"outputCapture": "std",
"console": "integratedTerminal"
}
]
}
通过上面的准备,文件目录如下:
main.js用BrowserWindow实例化:
const {app, BrowserWindow} = require('electron')
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {preload: path.join(__dirname, 'preload.js')}
})
win.loadFile('index.html')
}
app.whenReady().then( ()=>{
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0)
createWindow()
})
} )
app.on('window-all-closed', () =>
{
if (process.platform !== 'darwin') // macOS
app.quit()
})
在终端的cmd下输入 并enter:
electron .
对应的index.html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>Electron</h2>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
</body>
</html>
输出结果如下:
预加载脚本(preload.js)
要点:Electron的主进程(main.js)是一个拥有完全操作系统访问权限的Node.js的环境。
除了 Electron 模组 之外,您也可以访问 Node.js 内置模块 和所有通过 npm 安装的包。
另一方面,出于安全原因,渲染进程默认跑在网页页面上,而并非 Node.js里。
因此为了将 Electron 的不同类型的进程桥接在一起,我们需要使用被称为 预加载 的特殊脚本。
用法如下:
首先创建一个preload.js的文件,然后用contextBridge将一个全局变量Pre与想要加载的模块桥接(暴露给渲染进程)。
接着,在main.js里面的BrowserWindow中添加:
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
然后就可以在渲染进程的renderer.js里面使用Pre。(现在不会用也无妨,后面会有例子。)
进程之间通信
首先在preload.js里用contextBridge.exposeInMainWorld将一个函数(如ping)暴露:
ping: () => ipcRenderer.invoke('ping')
ipcRenderer.invoke('ping')表示触发主进程对应的ping函数。
然后在main.js中,在创建app->ready之后,就处理ping函数:
ipcMain.handle('ping', () => '来自main.js的消息')
然后就可以在渲染进程的js中使用了:
const func = async () => {
const response = await window.versions.ping()
console.log(response) // 打印 'pong'
}
const btn = document.getElementById('btn')
btn.onclick=function(){
func()
}