1.创建electron项目

对应:https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-first-app


一、本节在教程里的位置与目标

  • 位置:Electron 教程第 2 部分(前面还有「基本要求」等)。
  • 目标 :会建一个最小的 Electron 项目,能在终端里真正跑起来一个带窗口的应用。
  • 后续预告:预加载脚本、加功能、打包、发布与更新会在后面章节讲。

二、环境与工具链要点

|------------------------------|---------------------------------------------------------------------------------|
| 要点 | 说明 |
| Windows 不要用 WSL 跟本教程 | 在 WSL 里跑容易踩坑,尽量用原生 Windows 环境或按官方文档单独处理。 |
| 以 npm 为中心 | 项目以 package.json 为入口配置;Electron 打包链依赖磁盘上真实存在的 node_modules。 |
| Yarn Berry / pnpm | 若用它们,需按文档配置(如 Yarn 的 nodeLinker: node-modules、pnpm 的 hoisted 等),否则和打包工具预期不一致。 |


三、创建项目的步骤⭐

  1. 建目录 → mkdir my-electron-app && cd my-electron-app
  2. npm init → 生成 package.json
  3. 约定 :
    • main********指向 main.js(主进程入口)
    • author、license、description 先随便填也行,但后面打包会用到,建议认真填
  4. 安装 Electron :npm install electron --save-dev
  5. 为什么是 devDependency?
    • 运行时你会用到 Electron 的 JS API,但真正绑定的原生二进制 由打包阶段处理;日常开发用 dev 依赖即可,不必当成「线上 npm 生产依赖」那套来理解。
  6. 不要 --ignore-scripts:安装时要能跑 Electron 的 postinstall,否则可能装不完整。
  7. 加 .gitignore:至少忽略 node_modules(可直接用 GitHub 的 Node 模板)。

四、主进程:从一行 log 到打开窗口

4.1 入口与启动命令

  • package.json********里的 main:指定主进程入口文件(例如 main.js)。
  • scripts.start:"start": "electron ."
    • electron . = 在当前目录找 main 指向的文件,以开发方式跑起来。
  • 主进程本质是 Node 环境 ,所以一开始哪怕只有 console.log 也能验证入口是否配对。

4.2 最小窗口代码在做什么(概念版)⭐

  • require('electron') 里常用:app(应用生命周期)、BrowserWindow(窗口)。
  • createWindow():new BrowserWindow({ width, height }),再 win.loadFile('index.html') 加载本地页面。
  • app.whenReady().then(...):在 ready********之后 才能安全创建窗口。
    • 教程强调:优先用 app.whenReady(),而不是自己 app.on('ready'),可避免一些历史坑(官方 issue 有说明)。
4.2.1 app:应用程序的生命周期⭐️

BrowserWindow:创建并管理浏览器窗口⭐

总结:

  • app:
    • 应用模块/应用程序对象,控制应用生命周期;是整个electron程序的"总开关+管家"
    • 用途:app.whenReady()(准备好了再干活)、app.quit()(退出)、监听 window-all-closed、activate 等
  • BrowserWindow:
    • 浏览器窗口,屏幕上的一个活多个窗口

    • 用途:设置宽高、loadFile / loadURL、关窗、最小化等和"某一个窗口"相关的事。

      const { app, BrowserWindow } = require('electron')
      /*
      app:应用程序的生命周期
      BrowserWindow:浏览器窗口
      createWindow:创建浏览器窗口
      loadFile:加载HTML文件
      whenReady:当应用程序准备好时创建窗口
      activate:当应用程序激活时创建窗口
      window-all-closed:当所有窗口关闭时退出应用程序
      */
      const path = require('path')

      function createWindow() {
      const win = new BrowserWindow({
      width: 900,
      height: 640,
      webPreferences: {
      // 学习阶段先保持默认;后续接 Vue3 时再按需加 preload、关闭 nodeIntegration 等
      },
      })

      win.loadFile(path.join(__dirname, 'index.html'))
      }

      app.whenReady().then(() => {
      createWindow()

      app.on('activate', () => {
      if (BrowserWindow.getAllWindows().length === 0) createWindow()
      })
      })

      app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') app.quit()
      })

4.3 渲染进程(和你前端工作的关系)

  • 窗口里显示的每个页面,跑在单独的渲染器进程里。
  • 渲染进程里可以用熟悉的 Web API、打包工具(webpack 等)、Vue/React ------和做网页很像,但和主进程是隔离的(安全模型后面「预加载脚本」会展开)。

4.4 index.html 里 CSP 的意义(先有个印象)

  • Content-Security-Policy 限制默认只信任同源、script-src 'self',是安全基线;后面接 Vue、接外部脚本时要和 CSP 一起设计,否则容易被策略拦住。

五、窗口生命周期:为什么要多写几行

这是「桌面端体验」和「纯网页」差别很大的地方。

  1. Windows / Linux :习惯上关掉所有窗口 = 退出应用
    • 监听 window-all-closed,若非 macOS(process.platform !== 'darwin')则 app.quit()。
  2. macOS :关掉窗口后,Dock 里应用常还在 ;用户再点图标时期望再开一个窗口
    • 在 ****app.whenReady()****之后 监听 activate,若 BrowserWindow.getAllWindows().length === 0 就再调一次 createWindow()。
  3. 平台判断 :用 process.platform,Electron 主要关心 win32****/**** linux****/**** darwin。

六、可选:用 VS Code 同时调试主进程 + 渲染进程(结构理解)

  • Main :type: node,runtimeExecutable 指向项目里的 electron,并加 --remote-debugging-port=9222。
  • Renderer :type: chrome,request: attach,挂到该端口。
  • Compound :Main + renderer 一次启两套调试。
  • 注意 :附加调试器有「连上慢」的问题,前几行可能断不到,可用刷新或短暂 setTimeout 缓解。

七、和 Vue3 结合的「预习心态」(本节教程没细讲,但你要知道)

  • Vue3 的 UI :通常跑在渲染进程 (例如 index.html 挂一个 #app,或用 Vite 开发服务器------那是进阶整合方式)。
  • 主进程 :负责窗口、系统菜单、文件读写等「有权限」的事;不要 在渲染进程里随便 require('fs') 乱来,后面会学 preload + contextBridge 做安全桥接。

本节你只要先建立心智模型:一个 Node 主进程 + 多个 Chromium 渲染进程。


八、一句话总结(背这个就够复盘)

Electron 应用是 npm 项目 ;main********指定主进程 JS ,主进程用 app****+**** BrowserWindow 在 whenReady********后 创建窗口并 loadFile;页面在渲染进程 里像网页一样跑;关窗是否退出 要按 Windows/Linux 与 macOS 分别处理 window-all-closed****/**** activate;Electron 装在 devDependencies,安装时不要禁掉 postinstall 脚本。


如果你愿意,下一篇学习记录我可以按同样结构帮你整理「使用预加载脚本」那一章,并顺带画一张「主进程 / 预加载 / 渲染进程 / Vue」数据流简图,方便你对接 Vue3。

九、问题总结

|----------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 问题 | 原因 | 解决办法 |
| 安装/启动报 Electron failed to install correctly******,下载很慢或****** Fetch******/****** terminate报错 | Electron 本体(Chromium)要从外网拉 zip,国内常慢或中断;v42 还在首次运行 electron时才下载 | 项目里用 .npmrc配 electron_mirror(如 npmmirror);失败则删 node_modules/electron 再 npm install,再 npm run start |
| Node 版本不对、装依赖报错 | Electron 42 要求 Node ≥ 22.12 | 用 nvm use 22(或同等级 22.x),与 package.json 里 engines 一致 |
| app为 undefined******/****** whenReady报错 | 环境里有 ELECTRON_RUN_AS_NODE=1 时,require('electron') 会变成路径字符串而不是 API | start脚本里先 env -u ELECTRON_RUN_AS_NODE再执行 electron .(你当前 macOS 方案) |

为什么脚本start要由"electron ."改成"start": "env -u ELECTRON_RUN_AS_NODE electron ."?

原因说明

ELECTRON_RUN_AS_NODE=1 时,Electron 会按 「当成普通 Node 来跑」 的模式工作(给工具链、脚本用的能力),不会按桌面应用主进程那样注入真正的 electron API。

这时在入口里写 require('electron'),很容易拿到的是 npm 包那层包装(甚至是路径字符串),没有 app、BrowserWindow 等,于是会出现 app 为 undefined、whenReady 报错之类的问题。

某些终端/IDE/Agent 环境会 默认带上 ELECTRON_RUN_AS_NODE=1,所以用:

env -u ELECTRON_RUN_AS_NODE electron .

表示:只对这一次启动 从环境里 去掉 这个变量,让进程走 正常的 Electron 桌面应用模式。

  • 若你本机终端里 从来没有 设置过 ELECTRON_RUN_AS_NODE,env -u 一般也没副作用(未设置时去掉它仍然合法)。
  • 若你 100% 确定 环境干净,也可以继续用 electron .;加上 env -u 是为了 在「被污染」的环境里也能稳定启动。
相关推荐
月走乂山1 天前
DSH 桌面版用 DeepSeek 报 REQUEST_EXTENSION 的根因定位与修复
electron·node.js·插件系统·deepseek·bug排查·dsh·deepseek harness
mont evergreen2 天前
一封从外部世界寄来的信:二维码数据如何穿越三重门,抵达你的屏幕
electron·vue·事件
fellow993 天前
DSH Desktop:把 DeepSeek Harness 变成真正的桌面应用
electron·agent·ai编程·deepseek
CDwenhuohuo4 天前
electron pc项目打包成桌面端
前端·javascript·electron
不可能片场5 天前
命令行中文变问号 我用环境变量救了场
前端·electron
不可能片场5 天前
AI视频口型对齐 用音频驱动说话镜头
前端·electron
Zoom6 天前
【开源】7 天,我用 Rust 复刻了 FinalShell!Rhost v1.0.0 发布
rust·electron·shell
爱丶不疚7 天前
Electron: Sentry 都采集了什么?你知道吗
前端·electron
格数致用7 天前
03- Luckysheet与Vue3+Electron集成实战指南
electron·vue3·luckysheet