當你衝這個標題點進來的時候,我猜你一定知道 React 是什麼,更多詳情請戳這裡,就不介紹React了,一個神般存在的前端框架。另外,瀏覽器和移動端橫行的時代,為什麼還需要桌面應用?我就不解釋了,反正優點很多,做為技術多學一點總沒錯。
Electron 簡單介紹
是什麼?
官網是這麼介紹的:
Electron is an open source library developed by GitHub for building cross-platform desktop applications with HTML, CSS, and JavaScript. Electron accomplishes this by combining Chromium and Node.js into a single runtime and apps can be packaged for Mac, Windows, and Linux.
簡單翻譯一下就是:
Electron 是一個由 GitHub 開發的開源庫,通過將 Chromium) 和Node.js 組合並使用 HTML,CSS 和 JavaScript 進行構建 Mac,Windows,和 Linux 跨平臺桌面應用程式。
隱藏意思:
讓前端開發者快樂簡單擁抱桌面應用!
原理是?
上面已將說了,Electron 通過將 Chromium 和 Node.js 組合到單個 runtime 中來實現的。
node.js:
如果你不知道 node.js,那還等什麼快戳這裡,看一看世界上最溫柔可愛的語言。它藉助於 Google 的 V8 引擎,Node.js 是一個能夠在伺服器端執行 JavaScript 的開放原始碼、跨平臺 JavaScript 執行環境,更多解釋請戳維基百科。
Chromium:
Chromium 或許你沒聽說過,但是你一定聽說過 chrome 吧!Chromium 是 Google 的開源瀏覽器,是 chrome 背後的那個不太穩定更新快的兄弟版,詳情戳這裡。
組合:
Electron 建立的應用使用網頁作為其 GUI ,因此你可以將其當成由 JavaScript 控制的迷你精簡版Chromium 瀏覽器。也可以將 Electron 當成 node.js 變體,只不過它更專注於桌面應用而非 Web 伺服器。在 Electron 中, 把 package.json 中設定的 main 指令碼的所在程序稱為 主程序。這個程序中執行的指令碼也可通過建立網頁這種方式來展現其 GUI。 因為 Electron 是通過 Chromium 來顯示頁面,所以 Chromium 自帶的多程序架構也一同被利用。這樣每個頁面都執行著一個獨立的程序,它們被統稱為 渲染程序。通常來說,瀏覽器中的網頁會被限制在沙盒環境中執行並且不允許訪問系統原生資源。但是由於 Eelectron 使用者可在頁面中呼叫 Node.js API,所以可以和底層作業系統直接互動。
優缺點?
總之,優點肯定大於缺點。
優點:
方便快捷的開發桌面應用,跨平臺,對前端開發者友好,活躍的社群,豐富的api......
缺點:
效能肯定比不上原生的桌面應用,釋出的包貌似有一點點大。
怎麼開始?
如果不是假前端,那麼你電腦肯定安裝好了 git 和 node。
# github上有一個 electron-quick-start 倉庫克隆下來git clone https://github.com/electron/electron-quick-start# 進入資料夾cd electron-quick-start# 安裝依賴包並執行npm install && npm start複製程式碼
然後,你桌面應用就建立成功了如下圖所示!
開啟你的 electron-quick-start 資料夾,你的專案結構如下圖:
其中,main.js 是你的啟動檔案,index.html 是你的入口檔案。
React 結合 Electron
上面簡單的介紹了一下 Electron,下面介紹一下如何將 React 和 Electron 結合起來。
建立一個React專案
首先你得有一個 React 專案,由於太多繁瑣的配置和懶惰的自己,我們這裡就用 Facebook 提供的 create-react-app 來快速建立一個 knownsec-fed 專案。
# 安裝 create-react-app 命令,如果已將安裝請忽略npm install -g create-react-app# 建立 knownsec-fed 專案create-react-app knownsec-fed# 啟動專案( create-react-app 真的超級方便啊)cd knownsec-fed && npm start複製程式碼於是,瀏覽器 http://localhost:3000/ 就會出現著如下圖介面,一個 react 專案建立成功:
新增 Electron 包
# 在knownsec-fed 目錄下安裝 Electron 包npm install -save electron複製程式碼相關配置
配置 main.js
knownsec-fed 根目錄(不是 src 目錄)下面新建 main.js 檔案,這個檔案和 electron-quick-start 中的官方預設 main.js 幾乎一模一樣,只修改了載入應用這入口這一個地方:
// 引入electron並建立一個Browserwindowconst {app, BrowserWindow} = require('electron')const path = require('path')const url = require('url')// 保持window物件的全域性引用,避免JavaScript物件被垃圾回收時,視窗被自動關閉.let mainWindowfunction createWindow () {//建立瀏覽器視窗,寬高自定義具體大小你開心就好mainWindow = new BrowserWindow({width: 800, height: 600}) /* * 載入應用----- electron-quick-start中預設的載入入口 mainWindow.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true })) */ // 載入應用----適用於 react 專案 mainWindow.loadURL('http://localhost:3000/'); // 開啟開發者工具,預設不開啟 // mainWindow.webContents.openDevTools() // 關閉window時觸發下列事件. mainWindow.on('closed', function () { mainWindow = null })}// 當 Electron 完成初始化並準備建立瀏覽器視窗時呼叫此方法app.on('ready', createWindow)// 所有視窗關閉時退出應用.app.on('window-all-closed', function () { // macOS中除非使用者按下 `Cmd + Q` 顯式退出,否則應用與選單欄始終處於活動狀態. if (process.platform !== 'darwin') { app.quit() }})app.on('activate', function () { // macOS中點選Dock圖示時沒有已開啟的其餘應用視窗時,則通常在應用中重建一個視窗 if (mainWindow === null) { createWindow() }})// 你可以在這個指令碼中續寫或者使用require引入獨立的js檔案. 複製程式碼配置 package.json
{ "name": "knownsec-fed", "version": "0.1.0", "private": true, "main": "main.js", // 配置啟動檔案 "homepage":".", // "dependencies": { "electron": "^1.7.10", "react": "^16.2.0", "react-dom": "^16.2.0", "react-scripts": "1.1.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject", "electron-start": "electron ." // 配置electron的start,區別於web端的start }} 複製程式碼啟動 Electron
# 啟動react專案npm start# 啟動electronnpm run electron-start複製程式碼支援熱除錯,當你修改程式碼後,桌面應用也將會重新更新。
打包
打包 react 專案
首先修改 main.js, 因為現在你要將 react 專案打包在 build 資料夾下面,所以載入應用處改成如下!當然也可在某個配置檔案裡面配置是否屬於開發,此處用if判斷一下從未進行選擇執行哪段載入應用程式碼。但是這裡為了簡便,暫且使用直接修改的方式:
// 載入應用----react 打包mainWindow.loadURL(url.format({ pathname: path.join(__dirname, './build/index.html'), protocol: 'file:', slashes: true}))// 載入應用----適用於 react 開發時專案// mainWindow.loadURL('http://localhost:3000/');複製程式碼
預設情況下,homepage 是 http://localhost:3000,build 後,所有資原始檔路徑都是 /static,而 Electron 呼叫的入口是 file :協議,/static 就會定位到根目錄去,所以找不到靜態檔案。在 package.json 檔案中新增 homepage 欄位並設定為"."後,靜態檔案的路徑就變成了相對路徑,就能正確地找到了新增如下配置:
"homepage":"."複製程式碼
然後就開始打包 react:
npm run-script build複製程式碼
此時,根目錄下面將多出一個build資料夾。
打包 electron
常用打包外掛
electron-builderelectron-packager安裝electron-packager
# knownsec-fed目錄下安裝electron-packager包npm install electron-packager --save-dev# 安裝electron-packager命令npm install electron-packager -g複製程式碼
electron-packager命令介紹
electron-packager <location of project> <name of project> <platform> <architecture> <electron version> <optional options>複製程式碼location of project: 專案的本地地址,此處我這邊是 ~/knownsec-fedlocation of project: 專案名稱,此處是 knownsec-fedplatform: 打包成的平臺architecture: 使用 x86 還是 x64 還是兩個架構都用electron version: electron 的版本
於是,根據我這邊的情況在 package.json 檔案的在 scripts 中加上如下程式碼:
"package": "electron-packager ~/knownsec-fed/build knownsec-fed --all --out ~/ --version 1.7.10 複製程式碼
開始打包
npm run-script package複製程式碼
提醒
由於打包的時候會把瀏覽器核心完整打包進去,所以就算你的專案開發就幾百k的資源,但最終的打包檔案估計也會比較大。
其它
此文章未涉及 Electron 具體的技術,只是簡單的介紹了一下 react + electron 的一個配置及打包的流程。或許以後會寫關於 Electron 的技術細節。Electron 有著非常強大的 api,其背後涉及的技術也非常多。