NodeJs 桌面开发学习 electron.js (一)

发布于:2025-08-19 ⋅ 阅读:(18) ⋅ 点赞:(0)

今天开始学习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 预处理暴露到主页面的对象设置监听方法监听主线程 返回消息。

三、效果


网站公告

今日签到

点亮在社区的每一天
去签到