今天開始學習NodeJs 關于 桌面應用的內容,長期目標是 React + electron 實現一個桌面應用。
今天先實現一個簡單的目標,搭建一個Electron + ts 項目架構,并實現主業務線程 和前端渲染線程的交互
一、代碼結構和配置
例子項目結構大致如下:
package.json
{"name": "electron-ts-demo","version": "1.0.0","main": "dist/main.js","scripts": {"build": "tsc && xcopy /y src\\renderer\\*.html dist\\renderer\\","watch": "tsc -w","start": "electron .","dev": "concurrently \"npm run watch\" \"npm run start\""},"devDependencies": {"concurrently": "^9.2.0","electron": "^37.3.0","typescript": "^5.3.2"},"dependencies": {}
}
這里用到一個concurrently 包 是實現多條命令并行執行的工具。
tsconfig.json
{"compilerOptions": {"target": "ES2020","module": "commonjs","sourceMap": true,"outDir": "dist","strict": true,"esModuleInterop": true,"skipLibCheck": true},"include": ["src/**/*"]
}
二、代碼實現
preload.ts
預處理實現
import { contextBridge, ipcRenderer } from 'electron';contextBridge.exposeInMainWorld('electronAPI', {sendMessage: (message: string) => ipcRenderer.send('message-from-renderer', message),onReply: (callback: (response: string) => void) => ipcRenderer.on('message-reply', (event, response) => callback(response))
});
實現渲染線程(頁面) 發送信息到 主線程,主返回信息到渲染線程 (通過回調的形式)
main.ts
import { app, BrowserWindow, ipcMain } from 'electron';
import path from 'path';let mainWindow: BrowserWindow;function createWindow() {mainWindow = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.join(__dirname, 'preload.js'),contextIsolation: true}});mainWindow.loadFile('dist/renderer/index.html');ipcMain.on('message-from-renderer', (event, msg: string) => {console.log('Received:', msg);event.reply('message-reply', `Main process received: ${msg}`);});
}app.whenReady().then(() => {createWindow();//macBook 兼容app.on("activate", () => {if (BrowserWindow.getAllWindows().length === 0) {createWindow();}});
});app.on("window-all-closed", () => {if (process.platform !== "darwin") {app.quit();}
});
上面實現了一個簡單的生成一個窗口的例子。使用我們預先準備的preload.js預處理。
通過 ipcMain 監聽 發生消息和返回回調。
index.html
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>Electron TS Demo</title><style>body {font-family: Arial;padding: 20px;}button {padding: 8px 16px;}</style></head><body><h1>Electron + TypeScript Demo</h1><button id="sendBtn">Send Message</button><div id="response"></div><script src="renderer.js"></script></body>
</html>
renderer.ts
const sendBtn = document.getElementById('sendBtn')!;
const responseDiv = document.getElementById('response')!;sendBtn.addEventListener('click', () => {console.log("sendBtn Click");window?.electronAPI.sendMessage('Hello from TypeScript');
});window?.electronAPI.onReply((response: string) => {console.log(response);responseDiv.textContent = response;
});
這里添加監聽 給主線程發送消息,通過 window.electronAPI 預處理暴露到主頁面的對象設置監聽方法監聽主線程 返回消息。