跳到主要內容

建立你的第一個應用程式

學習目標

在本教學的這部分,您將學習如何設定您的 Electron 專案並編寫一個最小的入門應用程式。在本節結束時,您應該能夠從終端機以開發模式執行一個可運作的 Electron 應用程式。

設定您的專案

避免 WSL

如果您使用的是 Windows 機器,請在遵循本教學時不要使用 Windows Subsystem for Linux (WSL),因為在嘗試執行應用程式時會遇到問題。

初始化您的 npm 專案

Electron 應用程式是使用 npm 搭建的,其中 package.json 檔案作為入口點。首先建立一個資料夾,並使用 npm init 在其中初始化一個 npm 套件。

mkdir my-electron-app && cd my-electron-app
npm init

此命令將提示您在 package.json 中設定一些欄位。為了本教學的目的,有幾個規則需要遵循

  • 進入點 應為 main.js(您將很快建立該檔案)。
  • 作者許可證描述 可以是任何值,但對於稍後的封裝將是必要的。

然後,將 Electron 安裝到您應用程式的 devDependencies 中,這是僅在開發環境中需要的外部套件依賴項列表,在生產環境中不需要。

為什麼 Electron 是 devDependency?

這似乎違反直覺,因為您的生產程式碼正在執行 Electron API。然而,封裝後的應用程式將捆綁 Electron 二進制檔案,無需將其指定為生產依賴項。

npm install electron --save-dev

在初始化您的套件並安裝 Electron 後,您的 package.json 檔案應如下所示。您現在也應該有一個包含 Electron 可執行檔的 node_modules 資料夾,以及一個指定要安裝的確切依賴項版本的 package-lock.json 鎖定檔。

package.json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jane Doe",
"license": "MIT",
"devDependencies": {
"electron": "23.1.3"
}
}
Electron 進階安裝步驟

如果直接安裝 Electron 失敗,請參閱我們的進階安裝文件,以取得關於下載鏡像、代理和疑難排解步驟的說明。

新增 .gitignore

.gitignore 檔案指定要避免使用 Git 追蹤的檔案和目錄。您應該將 GitHub 的 Node.js gitignore 範本的副本放入您專案的根資料夾中,以避免提交您專案的 node_modules 資料夾。

執行 Electron 應用程式

延伸閱讀

閱讀 Electron 的程序模型 文件,以更好地了解 Electron 的多個程序如何協同工作。

您在 package.json 中定義的 main 腳本是任何 Electron 應用程式的入口點。此腳本控制主程序,該程序在 Node.js 環境中執行,並負責控制您應用程式的生命週期、顯示原生介面、執行特權操作以及管理渲染器程序(稍後會詳細介紹)。

在建立您的第一個 Electron 應用程式之前,您將首先使用一個簡單的腳本來確保您的主程序入口點已正確設定。在您專案的根資料夾中建立一個 main.js 檔案,其中包含一行程式碼

main.js
console.log('Hello from Electron 👋')

由於 Electron 的主程序是 Node.js 執行時環境,您可以使用 electron 命令執行任意 Node.js 程式碼(您甚至可以將其用作 REPL)。若要執行此腳本,請將 electron . 新增到 package.json 的 scripts 欄位中的 start 命令。此命令將告訴 Electron 可執行檔在目前目錄中尋找主腳本,並以開發模式執行它。

package.json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jane Doe",
"license": "MIT",
"devDependencies": {
"electron": "23.1.3"
}
}
npm run start

您的終端機應印出 Hello from Electron 👋。恭喜,您已在 Electron 中執行了您的第一行程式碼!接下來,您將學習如何使用 HTML 建立使用者介面,並將其載入到原生視窗中。

將網頁載入到 BrowserWindow 中

在 Electron 中,每個視窗都會顯示一個網頁,該網頁可以從本機 HTML 檔案或遠端網址載入。在此範例中,您將載入本機檔案。首先在您專案的根資料夾中的 index.html 檔案中建立一個最基本的網頁

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
</body>
</html>

現在您有一個網頁,您可以將其載入到 Electron BrowserWindow 中。將您的 main.js 檔案的內容替換為以下程式碼。我們將分別解釋每個反白顯示的區塊。

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

const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})

win.loadFile('index.html')
}

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

匯入模組

main.js(第 1 行)
const { app, BrowserWindow } = require('electron')

在第一行中,我們使用 CommonJS 模組語法匯入兩個 Electron 模組

  • app,它控制您應用程式的事件生命週期。
  • BrowserWindow,它建立和管理應用程式視窗。
模組大寫慣例

您可能已經注意到 app 和 BrowserWindow 模組之間的大寫差異。Electron 在此處遵循典型的 JavaScript 慣例,其中 PascalCase 模組是可實例化的類別建構子(例如 BrowserWindow、Tray、Notification),而 camelCase 模組則不可實例化(例如 app、ipcRenderer、webContents)。

類型化的匯入別名

為了在編寫 TypeScript 程式碼時獲得更好的類型檢查,您可以選擇從 electron/main 匯入主程序模組。

const { app, BrowserWindow } = require('electron/main')

如需更多資訊,請參閱程序模型文件

Electron 中的 ES 模組

ECMAScript 模組(即使用 import 載入模組)在 Electron 28 及更高版本中受到支援。您可以在 我們的 ESM 指南中找到關於 Electron 中 ESM 狀態以及如何在我們的應用程式中使用它們的更多資訊。

編寫可重複使用的函數來實例化視窗

createWindow() 函數將您的網頁載入到新的 BrowserWindow 實例中

main.js(第 3-10 行)
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})

win.loadFile('index.html')
}

在應用程式準備就緒時呼叫您的函數

main.js(第 12-14 行)
app.whenReady().then(() => {
createWindow()
})

許多 Electron 的核心模組都是 Node.js 事件發射器,它們遵循 Node 的異步事件驅動架構。app 模組就是這些發射器之一。

在 Electron 中,只有在 app 模組的 ready 事件觸發後才能建立 BrowserWindow。您可以使用 app.whenReady() API 等待此事件,並在其 Promise 兌現後呼叫 createWindow()

資訊

您通常使用發射器的 .on 函數來監聽 Node.js 事件。

+ app.on('ready', () => {
- app.whenReady().then(() => {
createWindow()
})

然而,Electron 公開了 app.whenReady() 作為專門針對 ready 事件的輔助程式,以避免直接監聽該特定事件的細微陷阱。請參閱 electron/electron#21972 以取得詳細資訊。

此時,執行您的 Electron 應用程式的 start 命令應成功開啟一個視窗,顯示您的網頁!

您的應用程式在視窗中顯示的每個網頁都將在一個稱為渲染器程序的獨立程序中執行(或簡稱為渲染器)。渲染器程序可以存取與您用於典型前端網頁開發相同的 JavaScript API 和工具,例如使用 webpack 來捆綁和縮小您的程式碼,或使用 React 來建置您的使用者介面。

管理您應用程式的視窗生命週期

應用程式視窗在每個作業系統上的行為都不同。Electron 沒有預設強制執行這些慣例,而是讓您可以選擇在您的應用程式程式碼中實作它們,如果您希望遵循它們。您可以透過監聽 app 和 BrowserWindow 模組發出的事件來實作基本的視窗慣例。

程序特定的控制流程

檢查 Node 的 process.platform 變數可以幫助您在特定平台上有條件地執行程式碼。請注意,Electron 只能在三個可能的平台上執行:win32 (Windows)、linux (Linux) 和 darwin (macOS)。

當所有視窗關閉時結束應用程式(Windows 和 Linux)

在 Windows 和 Linux 上,關閉所有視窗通常會完全結束應用程式。若要在您的 Electron 應用程式中實作此模式,請監聽 app 模組的 window-all-closed 事件,並呼叫 app.quit() 以在使用者不是在 macOS 上時退出您的應用程式。

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

如果沒有開啟任何視窗,則開啟一個視窗 (macOS)

相反地,即使沒有任何視窗開啟,macOS 應用程式通常也會繼續執行。在沒有視窗可用時啟動應用程式應開啟一個新視窗。

若要實作此功能,請監聽 app 模組的 activate 事件,如果沒有 BrowserWindow 開啟,則呼叫您現有的 createWindow() 方法。

由於視窗無法在 ready 事件之前建立,因此您應該僅在應用程式初始化後才監聽 activate 事件。透過僅在您現有的 whenReady() 回呼中監聽 activate 事件來執行此操作。

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

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

最終入門程式碼

const { app, BrowserWindow } = require('electron/main')

const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})

win.loadFile('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()
}
})

選用:從 VS Code 除錯

如果您想使用 VS Code 除錯您的應用程式,您需要將 VS Code 連接到主程序和渲染器程序。以下是您可以執行的範例組態。在您專案中新的 .vscode 資料夾中建立一個 launch.json 組態

.vscode/launch.json
{
"version": "0.2.0",
"compounds": [
{
"name": "Main + renderer",
"configurations": ["Main", "Renderer"],
"stopAll": true
}
],
"configurations": [
{
"name": "Renderer",
"port": 9222,
"request": "attach",
"type": "chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Main",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": [".", "--remote-debugging-port=9222"],
"outputCapture": "std",
"console": "integratedTerminal"
}
]
}

當您從側邊欄選取「執行和除錯」時,「Main + renderer」選項將會出現,讓您可以設定中斷點並檢查主程序和渲染器程序中的所有變數以及其他項目。

我們在 launch.json 檔案中所做的是建立 3 個組態

  • Main 用於啟動主程序,並公開用於遠端除錯的連接埠 9222 (--remote-debugging-port=9222)。這是我們將用來連接 Renderer 除錯器的連接埠。由於主程序是 Node.js 程序,因此類型設定為 node
  • Renderer 用於除錯渲染器程序。由於主程序是建立程序的程序,因此我們必須「連接」到它 ("request": "attach"),而不是建立新的程序。渲染器程序是網頁程序,因此我們必須使用的除錯器是 chrome
  • Main + renderer 是一個 複合任務,可同時執行先前的任務。
注意

由於我們正在 Renderer 中連接到一個程序,因此您的程式碼的第一行可能會被跳過,因為除錯器可能沒有足夠的時間在它們執行之前連接。您可以透過重新整理頁面或在開發模式中執行程式碼之前設定逾時來解決此問題。

延伸閱讀

如果您想深入研究除錯領域,以下指南提供了更多資訊

摘要

Electron 應用程式是使用 npm 套件設定的。Electron 可執行檔應安裝在您專案的 devDependencies 中,並且可以使用 package.json 檔案中的腳本以開發模式執行。

可執行檔會執行在 package.json 的 main 屬性中找到的 JavaScript 入口點。此檔案控制 Electron 的主程序,該程序執行 Node.js 的實例,並負責您應用程式的生命週期、顯示原生介面、執行特權操作以及管理渲染器程序。

渲染器程序(或簡稱渲染器)負責顯示圖形內容。您可以透過將網頁指向網址或本機 HTML 檔案,將網頁載入到渲染器中。渲染器的行為與常規網頁非常相似,並且可以存取相同的網頁 API。

在本教學的下一節中,我們將學習如何使用特權 API 擴充渲染器程序,以及如何在程序之間進行通訊。