00 electron

01 electron 项目实战

环境搭建

1
2
npm init
npm install -D electron@30.0.0

初始化

package. json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "name": "eva",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "dev":"electron .",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "loyalvi",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "electron": "^30.0.0"
  }
}

index. js

1
2
3
4
5
6
7
8
9
10
11
const {app,BrowserWindow} = require('electron')
const minWindow = function(){
    let win = new BrowserWindow({
        width:800,
        height:600
    })
    win.loadFile('./page/index.html')
}
app.whenReady().then(() => {
    minWindow()
})

powershell

1
npm run dev

渲染进程和主进程的通信

ipcMain<->ipcRenderer

webPreferences

主进程配置后,可以在渲染进程使用 node 代码,安全性差不推荐。

1
2
3
4
webPreferences:{
nodeIntegration:true,//渲染进程使用 node 模块(required)
contextlsolation:false//关闭js隔离,可以在渲染进程使用electron模块
}

不考虑安全性,可以直接在渲染进程使用 ipcRenderer 方法直接和主进程通信

预加载

ipcMain<->preload<->ipcRenderer

主进程

index. js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const {app,BrowserWindow,ipcMain} = require('electron')
const path = require('node:path')
const minWindow = function(){
    let win = new BrowserWindow({
        width:800,
        height:600,
        webPreferences:{
            preload:path.join(__dirname,'./preload.js'),
        }
    })
    win.loadFile('./page/index.html')
    ipcMain.on('open-dev-tools',()=>{
        win.webContents.openDevTools()
    })
    ipcMain.on('close-dev-tools',()=>{
        win.webContents.closeDevTools()
    });
    ipcMain.handle('get-version',()=>{
        return process.versions;
    })
}
app.whenReady().then(() => {
    minWindow()
})

preload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const {ipcRenderer,contextBridge} = require('electron')
contextBridge.exposeInMainWorld('tools',{
    ipcSend:function (mes,...args){
        ipcRenderer.send(mes,...args)
    },
    ipcInvoke:function (msg){
        return ipcRenderer.invoke(msg);
    }
})
contextBridge.exposeInMainWorld('versions',{
    chrome:function (){
        return process.versions.chrome;
    },
    electron:function (){
        return process.versions.electron;
    },
    node:function (){
        return process.versions.node;
    }
})

渲染进程

index. html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 预加载js把方法暴露到windows对象里
let openDevToolsEl = document.getElementById('open-dev-tools');
openDevToolsEl.addEventListener('click',()=>{
window.tools.ipcSend('open-dev-tools')
})
let closeDevToolsEl = document.getElementById('close-dev-tools');
closeDevToolsEl.addEventListener('click',()=>{
window.tools.ipcSend('close-dev-tools')
})
let getVersionInfoEl = document.getElementById('get-version-info');
getVersionInfoEl.addEventListener('click',()=>{
document.getElementById('chrome-version').innerText = window.versions.chrome();
document.getElementById('election-version').innerText = window.versions.electron();
document.getElementById('node-version').innerText = window.versions.node();
})

webview

仍然涉及渲染进程和主进程的通信

主进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const {app,BrowserWindow,ipcMain,WebContentsView} = require('electron')
const path = require('node:path')
const minWindow = function(){
    let win = new BrowserWindow({
        width:800,
        height:600,
        webPreferences:{
            preload:path.join(__dirname,'./preload.js'),
        }
    })
    win.loadFile('./page/search.html')
    win.setMenu(null)
    let [width,height] = win.getContentSize();
    let webview = null;
    ipcMain.on('create-webview',()=>{
        if(webview === null){
            webview = new WebContentsView();
            webview.setBounds({
                x:0,
                y:40,
                width:width,
                height:height - 40,
            })
            win.contentView.addChildView(webview)
        }
    })
    ipcMain.on('search-loadurl',(event,url)=>{
        webview.webContents.loadURL(url);
    })
    win.on('resize',()=>{
        let [width,height] = win.getContentSize();
        if(webview !== null){
            webview.setBounds({
                x:0,
                y:40,
                width:width,
                height:height - 40,
            })
        }
    })
}
app.whenReady().then(() => {
    minWindow()
})

preload

1
2
3
4
5
6
7
8
9
const {ipcRenderer,contextBridge} = require('electron')
contextBridge.exposeInMainWorld('tools',{
    ipcSend:function (mes,...args){
        ipcRenderer.send(mes,...args)
    },
    ipcInvoke:function (msg){
        return ipcRenderer.invoke(msg);
    }
})

渲染进程

1
2
3
4
5
6
7
8
let submitEl = document.getElementById('submit');
submitEl.addEventListener('click',()=>{
window.tools.ipcSend('create-webview')
let type = document.getElementById('type').value;
let info = document.getElementById('info').value;
let url = type + info;
window.tools.ipcSend('search-loadurl',url)
})