人人都会AI编程

2.4 第一个 Electron 应用:主进程入口、页面加载、应用启动

更新时间:2026-07-11

搭建好开发环境之后,写一个能跑起来的 Electron 应用其实只需要三个文件:package.jsonmain.js 和一个 HTML 页面。这一节会手把手带你创建它们,让你真正看到 Electron 是如何把一个网页变成桌面程序的。

2.4.1 项目初始化与 package.json

首先,新建一个项目文件夹,并用 npm 初始化:

mkdir my-first-electron-app
cd my-first-electron-app
npm init -y

这时会生成一个默认的 package.json。你需要告诉 Electron 主进程的入口文件在哪里,同时添加启动脚本:

{
  "name": "my-first-electron-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^28.0.0"
  }
}

这里有几个关键点:

  • "main": "main.js":这是一个隐式的约定,告诉 Electron 应用程序应该从哪个文件启动主进程。
  • "start": "electron .":执行 npm start 时,会运行当前目录下的 Electron,它自动读取 package.json 中的 main 字段作为入口。

接着安装 Electron(因为前面搭建环境时已经在全局装过,但项目依赖里仍需要声明):

npm install --save-dev electron

2.4.2 主进程入口:main.js

主进程是整个应用的“心脏”。它的核心职责是创建窗口、管理应用状态以及处理系统级的交互。一个最精简的 main.js 代码如下:

// main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  // 创建一个窗口实例
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'), // 安全桥接
      nodeIntegration: false,        // 禁止渲染进程直接使用 Node.js
      contextIsolation: true,        // 开启上下文隔离
    },
  });

  // 加载 HTML 页面
  win.loadFile('index.html');
}

// Electron 初始化完成后调用 createWindow
app.whenReady().then(() => {
  createWindow();

  // macOS 特性:当点击 dock 图标且没有窗口时,重新创建窗口
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

// 所有窗口关闭时退出应用(macOS 除外)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

这段代码展示了几个重要的设计模式:

  • app.whenReady():Electron 需要时间完成底层初始化(例如设置内部协议、加载扩展等)。必须等这个 Promise 完成之后才能安全地创建窗口。
  • BrowserWindow:这是所有 UI 的载体。它的 webPreferences 配置决定了渲染进程的安全策略。现代 Electron 应用几乎都要开启 contextIsolation 并关闭 nodeIntegration,再通过 preload 脚本暴露有限的 API。
  • 窗口加载win.loadFile('index.html') 直接加载本地 HTML 文件。你也可以使用 win.loadURL 加载一个远程地址(如开发时的 localhost:3000)。
  • 生命周期处理window-all-closedactivate 事件是为了遵守不同操作系统的约定。在 Windows/Linux 上关闭所有窗口通常意味着退出应用;而 macOS 上应用即使没有窗口也仍然保持活动状态,点击 Dock 图标应重新创建窗口。

2.4.3 一个简单的 HTML 页面

在项目根目录新建 index.html,内容非常简单:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>我的第一个 Electron 应用</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      background: #f5f5f5;
    }
    h1 {
      color: #333;
    }
  </style>
</head>
<body>
  <h1>🎉 Hello Electron!</h1>
</body>
</html>

2.4.4 预加载脚本(preload.js)

虽然目前还没用到主进程的特殊能力,但既然在 main.js 里指定了 preload,我们应当创建一个占位的 preload.js 文件,否则启动时会报错:

// preload.js
// 目前为空,后续会在这里安全地暴露主进程的 API

preload.js 是连接安全世界(渲染进程)和特权世界(主进程)的桥梁,我们会在后续章节详细展开。

2.4.5 启动应用

一切就绪后,在终端执行:

npm start

你会看到一个干净的桌面窗口,中央显示着“🎉 Hello Electron!”,它的样式完全由 CSS 控制,窗口可以拖拽、最大化、关闭——行为就是一个标准的桌面程序。

这个窗口的背后:

  • 主进程 main.js 运行在 Node.js 环境,拥有对系统的完整访问权。
  • 渲染进程(就是 index.html 所在的环境)被严格隔离,默认不能直接碰触 Node.js 或 Electron 的原生模块,保证了前端代码的安全性。

如果你用的是 Chromium 内核,甚至可以按下 Ctrl+Shift+I(Windows/Linux)或 Cmd+Option+I(macOS)打开 DevTools,像调试普通网页一样检查元素、查看控制台输出。开发体验与 Web 开发完全一致。


至此,你已经完成了一个从零到一的 Electron 应用。它虽然简单,但已经包含了 Electron 最核心的骨架:package.json 定义入口、main.js 驱动主进程并创建窗口、index.html 提供界面、preload.js 预留安全通道。下一节我们会让这个应用“活”起来,添加 IPC 通信,真正感受前端与后端协作的魅力。