【Electron + React 教學】#01 環境建置:用 Vite 快速起步

測驗:Electron + React 環境建置

共 5 題,點選答案後會立即顯示結果

1. Electron 應用程式的「主程序」和「渲染程序」分別運行在什麼環境?

  • A. 主程序運行在瀏覽器,渲染程序運行在 Node.js
  • B. 主程序運行在 Node.js,渲染程序運行在瀏覽器
  • C. 兩者都運行在 Node.js 環境
  • D. 兩者都運行在瀏覽器環境

2. 在 electron-vite 專案結構中,React 的程式碼應該放在哪個目錄?

  • A. electron/ 目錄
  • B. main/ 目錄
  • C. src/ 目錄
  • D. preload/ 目錄

3. preload.ts 檔案的主要功能是什麼?

  • A. 設定應用程式的視窗大小和外觀
  • B. 作為主程序和渲染程序之間的橋樑,暴露特定功能
  • C. 預先載入所有 npm 套件
  • D. 處理應用程式的自動更新

4. 以下程式碼片段的作用是什麼?

app.whenReady().then(() => { createWindow() })
  • A. 當 Electron 準備好時,執行建立視窗的函式
  • B. 檢查應用程式是否已經在運行
  • C. 等待使用者點擊後才建立視窗
  • D. 在背景準備視窗但不顯示

5. 為什麼 Electron 要將主程序和渲染程序分開?

  • A. 為了提升應用程式的運行速度
  • B. 為了減少記憶體使用量
  • C. 為了安全性,避免渲染程序直接存取檔案系統
  • D. 為了支援多種程式語言

一句話說明

Electron 讓你用網頁技術(HTML、CSS、JavaScript)做出桌面應用程式。


前置知識

開始前,你應該已經有:

  • 基本 React 開發經驗(知道 component、useState)
  • Node.js 與 npm 使用經驗(會 npm installnpm run dev

Electron 是什麼?

Electron 是一個框架,讓你用 網頁技術 做出 桌面應用程式

常見的 Electron 應用:

  • VS Code(你可能正在用)
  • Discord
  • Slack
  • Notion

一句話翻譯:「把網頁包成 .exe 或 .app,可以存取電腦檔案系統」。


核心概念:主程序 vs 渲染程序

這是 Electron 最重要的概念,AI 生成的代碼你會一直看到。

┌─────────────────────────────────────────────┐
│              Electron 應用程式               │
├─────────────────────────────────────────────┤
│                                             │
│   ┌─────────────────┐                       │
│   │   主程序 Main    │  ← Node.js 環境       │
│   │   (main.js)     │  ← 管理視窗、存取檔案  │
│   └────────┬────────┘                       │
│            │                                │
│            │ 建立視窗                        │
│            ▼                                │
│   ┌─────────────────┐                       │
│   │ 渲染程序 Renderer│  ← 瀏覽器環境         │
│   │  (React 應用)    │  ← 畫面、使用者互動   │
│   └─────────────────┘                       │
│                                             │
└─────────────────────────────────────────────┘
Code language: CSS (css)

翻譯對照

程序 環境 負責什麼 類比
主程序 Main Node.js 管理視窗、存取檔案系統、系統層級操作 後端
渲染程序 Renderer 瀏覽器 畫面顯示、使用者互動 前端

Vibe Coder 必記

  • 看到 main.jselectron/main → 這是主程序,跑在 Node.js
  • 看到 src/ 裡的 React 代碼 → 這是渲染程序,跑在瀏覽器環境

30 秒建立專案

我們用 electron-vite 這個工具,一行指令搞定:

# 建立專案
npm create @electron-vite/app my-electron-app -- --template react-ts

# 進入專案
cd my-electron-app

# 安裝依賴
npm install

# 啟動開發模式
npm run dev
Code language: PHP (php)

這段指令做了什麼

  1. 建立一個叫 my-electron-app 的資料夾
  2. 使用 React + TypeScript 模板
  3. 安裝所有需要的套件
  4. 啟動開發伺服器(會自動開啟視窗)

專案結構速讀

my-electron-app/
├── electron/              ← 主程序代碼
│   ├── main.ts           ← 程式進入點(建立視窗)
│   └── preload.ts        ← 橋接主程序和渲染程序
├── src/                   ← 渲染程序代碼(React)
│   ├── App.tsx           ← React 主組件
│   └── main.tsx          ← React 進入點
├── electron.vite.config.ts ← Vite 設定
└── package.json           ← 專案設定

翻譯

檔案/資料夾 你要知道的
electron/main.ts 主程序進入點,AI 會在這裡建立視窗
electron/preload.ts 讓渲染程序可以呼叫主程序的功能
src/ 你熟悉的 React 代碼,畫面都在這裡

主程序代碼解讀

打開 electron/main.ts,你會看到類似這樣:

import { app, BrowserWindow } from 'electron'  // 從 electron 引入功能
import path from 'path'

function createWindow() {
  // 建立一個視窗
  const mainWindow = new BrowserWindow({
    width: 800,                    // 視窗寬度
    height: 600,                   // 視窗高度
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),  // 指定 preload 檔案
    },
  })

  // 載入畫面
  mainWindow.loadURL('http://localhost:5173')  // 開發時載入 Vite 伺服器
}

// 當 Electron 準備好時,建立視窗
app.whenReady().then(() => {
  createWindow()
})

// 當所有視窗關閉時,結束程式(macOS 除外)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
Code language: JavaScript (javascript)

逐行翻譯

import { app, BrowserWindow } from 'electron'
// ↑ app 是整個應用程式,BrowserWindow 是用來建立視窗的

const mainWindow = new BrowserWindow({ ... })
// ↑ 建立一個新視窗,大括號裡是設定

mainWindow.loadURL('http://localhost:5173')
// ↑ 視窗要顯示什麼內容(開發時是 Vite 伺服器)

app.whenReady().then(() => { ... })
// ↑ 當 Electron 準備好時,執行大括號裡的程式

app.on('window-all-closed', () => { ... })
// ↑ 當所有視窗關閉時,執行大括號裡的程式
Code language: JavaScript (javascript)

渲染程序代碼解讀

打開 src/App.tsx,這就是你熟悉的 React:

function App() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <h1>Hello Electron!</h1>
      <button onClick={() => setCount(count + 1)}>
        Count: {count}
      </button>
    </div>
  )
}
Code language: JavaScript (javascript)

跟一般 React 有什麼不同?

基本上沒有不同!渲染程序就是一個跑在 Electron 視窗裡的 React 應用。


常見的 AI 生成模式

模式 1:建立視窗

const win = new BrowserWindow({
  width: 1200,
  height: 800,
  webPreferences: {
    nodeIntegration: false,    // 安全設定:不讓渲染程序直接用 Node.js
    contextIsolation: true,    // 安全設定:隔離主程序和渲染程序
    preload: path.join(__dirname, 'preload.js'),
  },
})
Code language: JavaScript (javascript)

翻譯:「建立一個 1200×800 的視窗,並且套用安全設定」。

模式 2:監聽應用程式事件

app.on('ready', () => { ... })           // 應用準備好了
app.on('window-all-closed', () => { ... })  // 所有視窗關閉
app.on('activate', () => { ... })        // macOS 點擊 dock 圖示
Code language: PHP (php)

翻譯:「當 [事件] 發生時,執行 [動作]」。

模式 3:開發與正式環境判斷

if (process.env.NODE_ENV === 'development') {
  mainWindow.loadURL('http://localhost:5173')  // 開發:載入 Vite
} else {
  mainWindow.loadFile('dist/index.html')       // 正式:載入打包好的檔案
}
Code language: JavaScript (javascript)

翻譯:「開發時連本地伺服器,正式版載入打包好的 HTML」。


開發流程

# 啟動開發模式
npm run dev
Code language: PHP (php)

這會:

  1. 啟動 Vite 開發伺服器(處理 React)
  2. 啟動 Electron 主程序
  3. 自動開啟視窗
  4. 修改代碼會自動重新載入(熱重載)

Vibe Coder 檢查點

看到 Electron 專案時確認:

  • [ ] 分清楚哪些是主程序代碼(electron/),哪些是渲染程序(src/
  • [ ] 主程序有沒有正確建立 BrowserWindow
  • [ ] 有沒有設定 preload 檔案(主程序和渲染程序溝通用)
  • [ ] 開發和正式環境的載入方式是否不同

常見問題

Q:為什麼要分主程序和渲染程序?

安全性。渲染程序跑的是網頁,如果直接讓它存取檔案系統,惡意網站可能會做壞事。透過 preload 和 IPC(程序間通訊)來控制什麼功能可以用。

Q:preload.ts 是幹嘛的?

橋樑。它在渲染程序載入前執行,可以把主程序的特定功能「暴露」給渲染程序使用。下一篇會詳細說明。

Q:我可以用 npm 套件嗎?

  • 在渲染程序(React)裡:跟平常一樣用,但要注意是 瀏覽器環境
  • 在主程序裡:可以用 Node.js 套件(例如 fspath

延伸:知道就好

這些進階功能遇到再查:

  • IPC 通訊:主程序和渲染程序互傳訊息(下一篇會教)
  • 原生模組:使用 C++ 寫的套件
  • 自動更新:讓應用程式可以自動下載新版本
  • 打包發布:把應用程式打包成 .exe、.dmg、.AppImage

小結

這篇你學到了:

  1. Electron 是什麼:用網頁技術做桌面應用
  2. 核心架構:主程序(Node.js)+ 渲染程序(瀏覽器/React)
  3. 快速建立專案npm create @electron-vite/app
  4. 專案結構electron/ 是主程序,src/ 是渲染程序
  5. 開發流程npm run dev 啟動熱重載開發

下一篇,我們會學習主程序和渲染程序如何溝通(IPC 通訊)。

進階測驗:Electron + React 環境建置

測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。

1. 你需要在渲染程序中讀取使用者電腦上的檔案內容。應該怎麼做? 情境題

  • A. 直接在 React 組件中使用 require('fs') 讀取檔案
  • B. 在 BrowserWindow 設定中開啟 nodeIntegration: true
  • C. 透過 preload 暴露特定的檔案讀取功能,讓渲染程序呼叫
  • D. 使用瀏覽器的 File API 直接存取任意檔案路徑

2. 你執行 npm run dev 後,Electron 視窗開啟了但顯示空白頁面。可能的原因是什麼? 錯誤診斷

// electron/main.ts mainWindow.loadURL(‘http://localhost:5173’)
  • A. BrowserWindow 的寬高設定錯誤
  • B. Vite 開發伺服器尚未啟動完成,或埠號不是 5173
  • C. 缺少 preload.ts 檔案
  • D. React 組件沒有正確匯出

3. 你想讓 Electron 應用在 macOS 上點擊 Dock 圖示時重新開啟視窗。應該監聽哪個事件? 情境題

  • A. app.on('ready', ...)
  • B. app.on('window-all-closed', ...)
  • C. app.on('before-quit', ...)
  • D. app.on('activate', ...)

4. 以下程式碼有什麼問題? 錯誤診斷

// electron/main.ts const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, }, })
  • A. 視窗尺寸太小,應該至少 1024×768
  • B. 缺少 preload 設定,視窗無法顯示內容
  • C. 安全設定有風險:開啟 nodeIntegration 且關閉 contextIsolation 會讓渲染程序直接存取 Node.js
  • D. 應該使用 webPreferences: {} 空物件作為預設值

5. 你正在打包 Electron 應用程式準備發布。程式碼中需要判斷現在是開發模式還是正式環境來決定載入方式。最佳做法是? 情境題

  • A. 手動在程式碼中設定 const isDev = true,發布前改成 false
  • B. 使用 process.env.NODE_ENV === 'development' 判斷,開發時載入 Vite URL,正式版載入打包好的 HTML 檔案
  • C. 永遠使用 loadFile() 載入本地檔案
  • D. 永遠使用 loadURL() 載入 localhost

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *