知識(shí)分享:如何用Web前端技術(shù)開(kāi)發(fā)出桌面應(yīng)用程序?

## Web前端技術(shù)開(kāi)發(fā)桌面應(yīng)用的方式

- **CEF**:用 Chromium&[Webkit](https://baike.baidu.com/item/webkit/1467841?fr=aladdin "Webkit") 來(lái)呈現(xiàn) web 頁(yè)面,是客戶端里面嵌瀏覽器,瀏覽器里面跑網(wǎng)頁(yè)。

- **heX**:基于CEF,內(nèi)部整合了開(kāi)源項(xiàng)目 Chromium 及 [node.js](https://baike.baidu.com/item/node.js/7567977?fr=aladdin "node.js")。

- **nw**:基于Chromium 和 node.js,利用 web 方式開(kāi)發(fā)跨平臺(tái)桌面應(yīng)用的平臺(tái)技術(shù)。

- **electron**:底層也是基于Chromium 和 node.js。

- 等等。。。

## 案例實(shí)操~electron

electron 是 github 開(kāi)發(fā)的,用來(lái)開(kāi)發(fā)桌面應(yīng)用的一款前端框架

![](https://imgkr.cn-bj.ufileos.com/5dcb1686-18db-41c0-9ce1-064c21afe33f.png)

### 開(kāi)發(fā)環(huán)境

#### 安裝 node.js

[nodejs下載地址](https://nodejs.org/zh-cn/)

為了避免網(wǎng)絡(luò)問(wèn)題對(duì) Node 工作時(shí)的影響,我們安裝國(guó)內(nèi)的 node 鏡像 cnpm。

`npm install -g cnpm --registry=https://registry.npm.taobao.org`

#### 安裝 electron

`npm install --save-dev electron`

或者全局安裝

`npm install -g electron`

### 開(kāi)發(fā)工具

[VSCode](https://vscode.cdn.azure.cn/stable/ff915844119ce9485abfe8aa9076ec76b5300ddd/VSCodeUserSetup-x64-1.44.2.exe)

其實(shí) vscode 就是 electron 開(kāi)發(fā)的

### 開(kāi)發(fā)一個(gè)簡(jiǎn)易的 electron

Electron 應(yīng)用使用 JavaScript 開(kāi)發(fā),其工作原理和方法與 Node.js 開(kāi)發(fā)相同。 `electron` 模塊包含了 Electron 提供的所有 API 和功能,引入方法和普通 Node.js 模塊一樣:

```javascript

const electron = require('electron')

```

`electron` 模塊所提供的功能都是通過(guò)命名空間暴露出來(lái)的。 比如說(shuō): `electron.app`負(fù)責(zé)管理 Electron 應(yīng)用程序的生命周期, `electron.BrowserWindow`類負(fù)責(zé)創(chuàng)建窗口。下面是一個(gè)簡(jiǎn)單的`main.js`文件,它將在應(yīng)用程序準(zhǔn)備就緒后打開(kāi)一個(gè)窗口:

```javascript

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

function createWindow () {?

? // 創(chuàng)建瀏覽器窗口

? let win = new BrowserWindow({

? ? width: 800,

? ? height: 600,

? ? webPreferences: {

? ? ? nodeIntegration: true

? ? }

? })

? // 加載index.html文件

? win.loadFile('index.html')

}

app.whenReady().then(createWindow)

```

創(chuàng)建你想展示的 `index.html`:

```html

<!DOCTYPE html>

<html>

? <head>

? ? <meta charset="UTF-8">

? ? <title>Hello World!</title>

? ? <!-- https://electronjs.org/docs/tutorial/security#csp-meta-tag -->

? ? <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />

? </head>

? <body>

? ? <h1>Hello World!</h1>

? ? We are using node <script>document.write(process.versions.node)</script>,

? ? Chrome <script>document.write(process.versions.chrome)</script>,

? ? and Electron <script>document.write(process.versions.electron)</script>.

? </body>

</html>

```

### 啟動(dòng)

我們?cè)赻package.json`中已經(jīng)寫(xiě)好了啟動(dòng)命令,所以這里直接用 node 啟動(dòng)命令`npm start`就可以了,如果沒(méi)有配,也可以用`electron .`命令啟動(dòng)。

### 主進(jìn)程和渲染進(jìn)程

我們可以理解`package.json`中定義的入口文件就是主進(jìn)程,那一般一個(gè)程序只有一個(gè)主進(jìn)程,而我們可以利用一個(gè)主進(jìn)程,打開(kāi)多個(gè)子窗口。

由于 Electron 使用了 Chromium 來(lái)展示 web 頁(yè)面,所以 Chromium 的多進(jìn)程架構(gòu)也被使用到。每個(gè) Electron 中的 web 頁(yè)面運(yùn)行在它自己的渲染進(jìn)程中,也就是我們說(shuō)的渲染進(jìn)程。

也就是說(shuō)主進(jìn)程控制渲染進(jìn)程,一個(gè)主進(jìn)程可以控制多個(gè)渲染進(jìn)程。

![](https://imgkr.cn-bj.ufileos.com/5dcb1686-18db-41c0-9ce1-064c21afe33f.png)

您應(yīng)當(dāng)在 `main.js` 中創(chuàng)建窗口,并處理程序中可能遇到的所有系統(tǒng)事件。下面我們將完善上述例子,添加以下功能:打開(kāi)開(kāi)發(fā)者工具、處理窗口關(guān)閉事件、在 macOS 用戶點(diǎn)擊 dock 上圖標(biāo)時(shí)重建窗口,添加后,main. js 就像下面這樣:

```javascript

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

function createWindow () {?

? // 創(chuàng)建瀏覽器窗口

? const win = new BrowserWindow({

? ? width: 800,

? ? height: 600,

? ? webPreferences: {

? ? ? nodeIntegration: true

? ? }

? })

? // 并且為你的應(yīng)用加載index.html

? win.loadFile('index.html')

? // 打開(kāi)開(kāi)發(fā)者工具

? win.webContents.openDevTools()

}

app.whenReady().then(createWindow)

// 當(dāng)所有窗口都關(guān)閉時(shí)觸發(fā)此事件.

app.on('window-all-closed', () => {

? // 在 macOS 上,除非用戶用 Cmd + Q 確定地退出,

? // 否則絕大部分應(yīng)用及其菜單欄會(huì)保持激活。

? if (process.platform !== 'darwin') {

? ? app.quit()

? }

})

app.on('activate', () => {

? // 在macOS上,當(dāng)單擊dock圖標(biāo)并且沒(méi)有其他窗口打開(kāi)時(shí),

? // 通常在應(yīng)用程序中重新創(chuàng)建一個(gè)窗口。

? if (BrowserWindow.getAllWindows().length === 0) {

? ? createWindow()

? }

})

// In this file you can include the rest of your app's specific main process

// code. 也可以拆分成幾個(gè)文件,然后用 require 導(dǎo)入。

```

### git 上面的 demo 示例

```shell

# 克隆這倉(cāng)庫(kù)

git clone https://github.com/electron/electron-quick-start

# 進(jìn)入倉(cāng)庫(kù)

cd electron-quick-start

# 安裝依賴庫(kù)

npm install

# 運(yùn)行應(yīng)用

npm start

```

### electron-forge 構(gòu)建項(xiàng)目

```shell

# 全局安裝electron-forge

npm install electron-forge -g

#用electron-forge初始化一個(gè)項(xiàng)目

electron-forge init demo02

# 進(jìn)入到項(xiàng)目目錄

cd demo02

#啟動(dòng)項(xiàng)目

npm start

```

## 擴(kuò)展~開(kāi)發(fā)桌面百度

### 主進(jìn)程代碼

我們創(chuàng)建了主進(jìn)程對(duì)象 win 后,讓它直接加載百度的地址。

```js

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

function createWindow () {?

? // 創(chuàng)建瀏覽器窗口

? let win = new BrowserWindow({

? ? width: 800,

? ? height: 800,

? ? webPreferences: {

? ? ? nodeIntegration: true

? ? }

? })

? // 加載index.html文件

//? win.loadFile('index.html')

? win.loadURL("http://www.baidu.com")

}

app.whenReady().then(createWindow)

```

### 打包發(fā)布

我們希望使用`electron-packager`對(duì)應(yīng)用進(jìn)行打包發(fā)布,`electron-packager`的安裝方式如下:

```shell

#下載electron-packager打包插件

npm install electron-packager -g

#開(kāi)始打包

electron-packager ./ demo01 --win --out ./ --arch=x64 --app-version=0.0.1 --electron-version=8.2.5

```

我們還可以進(jìn)一步打包成可執(zhí)行文件

```shell

#下載windows系統(tǒng)可執(zhí)行文件打包插件

npm install -g electron-installer-windows

#開(kāi)始打包

electron-installer-windows --src demo01-win32-x64 --dest ./

```

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容