在上海樂字節(jié)學(xué)習(xí)的第三十七天(持續(xù)更新中)

如何用Web前端技術(shù)就能開發(fā)出桌面應(yīng)用程序?

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

  • CEF:用 Chromium&Webkit 來呈現(xiàn) web 頁面毛甲,是客戶端里面嵌瀏覽器,瀏覽器里面跑網(wǎng)頁锉试。

  • heX:基于CEF,內(nèi)部整合了開源項目 Chromium 及 node.js览濒。

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

  • electron:底層也是基于Chromium 和 node.js贷笛。

  • 等等应又。。乏苦。

案例實操~electron

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

開發(fā)環(huán)境

安裝 node.js

nodejs下載地址

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

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

安裝 electron

npm install --save-dev electron

或者全局安裝

npm install -g electron

開發(fā)工具

VSCode

其實 vscode 就是 electron 開發(fā)的

開發(fā)一個簡易的 electron

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

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" contenteditable="false" cid="n37" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">const electron = require('electron')</pre>

electron 模塊所提供的功能都是通過命名空間暴露出來的奖磁。 比如說: electron.app負責(zé)管理 Electron 應(yīng)用程序的生命周期改基, electron.BrowserWindow類負責(zé)創(chuàng)建窗口繁疤。下面是一個簡單的main.js文件咖为,它將在應(yīng)用程序準備就緒后打開一個窗口:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" contenteditable="false" cid="n40" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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)</pre>

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

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" contenteditable="false" cid="n42" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>

<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></pre>

啟動

我們在package.json中已經(jīng)寫好了啟動命令,所以這里直接用 node 啟動命令npm start就可以了稠腊,如果沒有配躁染,也可以用electron .命令啟動。

主進程和渲染進程

我們可以理解package.json中定義的入口文件就是主進程架忌,那一般一個程序只有一個主進程吞彤,而我們可以利用一個主進程,打開多個子窗口叹放。

由于 Electron 使用了 Chromium 來展示 web 頁面饰恕,所以 Chromium 的多進程架構(gòu)也被使用到。每個 Electron 中的 web 頁面運行在它自己的渲染進程中井仰,也就是我們說的渲染進程埋嵌。

也就是說主進程控制渲染進程,一個主進程可以控制多個渲染進程俱恶。

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

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" contenteditable="false" cid="n54" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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')
?
// 打開開發(fā)者工具
win.webContents.openDevTools()
}
?
app.whenReady().then(createWindow)
?
// 當(dāng)所有窗口都關(guān)閉時觸發(fā)此事件.
app.on('window-all-closed', () => {
// 在 macOS 上,除非用戶用 Cmd + Q 確定地退出荔烧,
// 否則絕大部分應(yīng)用及其菜單欄會保持激活吱七。
if (process.platform !== 'darwin') {
app.quit()
}
})
?
app.on('activate', () => {
// 在macOS上,當(dāng)單擊dock圖標并且沒有其他窗口打開時鹤竭,
// 通常在應(yīng)用程序中重新創(chuàng)建一個窗口踊餐。
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
?
// In this file you can include the rest of your app's specific main process
// code. 也可以拆分成幾個文件,然后用 require 導(dǎo)入臀稚。
?</pre>

git 上面的 demo 示例

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="shell" contenteditable="false" cid="n57" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 克隆這倉庫
git clone https://github.com/electron/electron-quick-start

進入倉庫

cd electron-quick-start

安裝依賴庫

npm install

運行應(yīng)用

npm start</pre>

electron-forge 構(gòu)建項目

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="shell" contenteditable="false" cid="n60" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 全局安裝electron-forge
npm install electron-forge -g
?

用electron-forge初始化一個項目

electron-forge init demo02
?

進入到項目目錄

cd demo02
?

啟動項目

npm start</pre>

擴展~開發(fā)桌面百度

主進程代碼

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

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="js" contenteditable="false" cid="n65" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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)</pre>

打包發(fā)布

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

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="shell" contenteditable="false" cid="n68" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(255, 255, 255); position: relative !important; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#下載electron-packager打包插件
npm install electron-packager -g

開始打包

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窜管,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子稚机,更是在濱河造成了極大的恐慌幕帆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赖条,死亡現(xiàn)場離奇詭異失乾,居然都是意外死亡常熙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門碱茁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裸卫,“玉大人,你說我怎么就攤上這事纽竣∧够撸” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵蜓氨,是天一觀的道長聋袋。 經(jīng)常有香客問我,道長穴吹,這世上最難降的妖魔是什么舱馅? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮刀荒,結(jié)果婚禮上代嗤,老公的妹妹穿的比我還像新娘。我一直安慰自己缠借,他們只是感情好干毅,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泼返,像睡著了一般硝逢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绅喉,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天渠鸽,我揣著相機與錄音,去河邊找鬼柴罐。 笑死徽缚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的革屠。 我是一名探鬼主播凿试,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼似芝!你這毒婦竟也來了那婉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤党瓮,失蹤者是張志新(化名)和其女友劉穎详炬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寞奸,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡呛谜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年傲醉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呻率。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖呻引,靈堂內(nèi)的尸體忽然破棺而出礼仗,到底是詐尸還是另有隱情,我是刑警寧澤逻悠,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布元践,位于F島的核電站,受9級特大地震影響童谒,放射性物質(zhì)發(fā)生泄漏单旁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一饥伊、第九天 我趴在偏房一處隱蔽的房頂上張望象浑。 院中可真熱鬧,春花似錦琅豆、人聲如沸愉豺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚪拦。三九已至,卻和暖如春冻押,著一層夾襖步出監(jiān)牢的瞬間驰贷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工洛巢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留括袒,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓稿茉,卻偏偏與公主長得像箱熬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狈邑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容