開發一個React + Electron應用

breeze發表於2019-03-09

最近用React + Electron開發了一個RSS閱讀器,開源在:github.com/breeze2/bre…,這裡記錄一下大致的開發過程。

Breader

初始化

建立專案

以普通的React應用做基礎,一步步初始化專案。預先安裝yarn工具,用yarn來建立一個React應用專案,假設名字叫demo,再引入Electron依賴。

$ cd /PATH/TO/PROJECTS
$ yarn create react-app YOUR_APP_NAME
$ cd /PATH/TO/PROJECTS/YOUR_APP_NAME
$ yarn add electron --dev
複製程式碼

配置入口檔案

建立專案後,大致的目錄結構如下:

|-->demo
    |-->node_modules
        |--...
    |-->public
        |--index.html
        |--...
    |-->src
    |--package.json
    |--...
複製程式碼

一般來說,React應用(測試環境下)的入口檔案就是public/index.html,而Electron應用的入口檔案最好也放在public目錄下,並命名為electron.js(這樣electron-builder可以自動識別)。

先在package.json中lectron應用的入口檔案,新增main配置:

{
  ...
  "main": "public/electron.js",
  ...
}
複製程式碼

public/electron.js程式碼:

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

let mainWindow

function createWindow() {
    mainWindow = new BrowserWindow({
        width: 960,
        height: 600,
    })
    mainWindow.loadFile('index.html')
    mainWindow.webContents.openDevTools()
    mainWindow.on('closed', function () {
        mainWindow = null
    })
}

app.on('ready', createWindow)

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

app.on('activate', function () {
    if (mainWindow === null) {
        createWindow()
    }
})
複製程式碼

在執行執行yarn electron ./命令就可以啟動Electron應用了,不過React應用還沒啟動起來。

啟動應用

一般用yarn react-scripts start命令,就可以將React應用掛載在本地3000埠上( http://localhost:3000 ),用於開發除錯。要用React結合Electron一起開發除錯,先安裝electron-is-dev來識別當前是否開發環境。

$ yarn add electron-is-dev
複製程式碼

一般開發環境是載入http://localhost:3000/,正式環境是載入../build/index.html檔案,所以修改public/electron.js程式碼(createWindow函式內):

const isDev = require('electron-is-dev')

...
--    // mainWindow.loadFile('index.html')
++    if (isDev) {
++        mainWindow.loadURL('http://localhost:3000/')
++    } else {
++        mainWindow.loadFile(path.join(__dirname, '/../build/index.html'))
++    }
...
複製程式碼

然後,在專案目錄下,開啟兩個終端,一個執行yarn react-scripts start,一個執行yarn electron ./,就可以開發除錯React + Electron應用了。 不用羨慕electron-vue,可以一句命令可以直接啟動,其實原理是一樣的。 要實現一句命令啟動也不難,只要把兩句命令合到一起執行就可以了。先安裝工具庫:

$ yarn add concurrently --dev
$ yarn add wait-on --dev
複製程式碼

修改package.json,新增一個electron-dev指令碼命令:

{
  ...
  "scripts": {
    ...
    "electron-dev": "concurrently \"BROWSER=none react-scripts start\" \"wait-on http://localhost:3000 && electron .\"",
    ...
  }
  ...
}
複製程式碼

這樣,執行一句yarn electron-dev就可以啟動React + Electron應用了。

JS執行時

一般來說,瀏覽器提供一種JS執行時,NodeJS提供另一種JS執行時,Electron則是將這兩種執行時結合到一起來提供。不過,這兩種執行時並不是完美地和睦相處,比如說使用webpack時,通過webpack打包的JS程式碼中,不能直接通過import關鍵字或者require函式來引入NodeJS提供的功能介面,因為webpack覆蓋了NodeJS自帶的require函式。 不過Electron中,window物件的require屬性會對映到NodeJS自帶的require函式上,比如要呼叫NodeJS提供的http介面,可以這樣寫:

const http = window.require('http')
複製程式碼

重新編譯NodeJS擴充套件

通常,純JS程式碼實現的工具庫都可以在Electron環境中執行。不過有些NodeJS的工具庫並不是純JS程式碼實現的,比如node-sqlite3node-sqlite3是C++編寫,算是NodeJS的擴充套件,而不是單純的工具庫。node-sqlite3需要針對Electron環境重新編譯,才能在Electron環境中執行。

electron-rebuild

electron-rebuild是專門Electron環境針對重新編譯NodeJS擴充套件的一個工具。 在專案目錄下,安裝electron-rebuild:

$ yarn add electron-rebuild --dev
複製程式碼

比如,重新編譯node-sqlite3,只需要:

$ yarn electron-rebuild -f -w sqlite3
複製程式碼

在MacOS系統上就是這麼簡單,在Windows系統就複雜一些。

Windows系統上重新編譯NodeJS擴充套件

在Windows系統上也一樣可以使用electron-rebuild工具,但必須預先配置好編譯環境。

首先,安裝window編譯工具:

$ npm install --global --production windows-build-tools
$ npm config set msvs_version 2017
複製程式碼

然後,下載並安裝Python2,必須Python2不能Python3,如果同時安裝了Python2和Python3,須給npm指定Python2可執行檔案路徑,避免呼叫了Python3:

$ npm config set python /path/to/executable/python2
複製程式碼

這樣,才能在Windows系統上呼叫electron-rebuild。如果electron-rebuild執行過程中,遇上CONNECT ERROR可能是網路問題,可以換成淘寶源再試試。

所以儘量少用NodeJS擴充套件,可以免去跨平臺時重新編譯的麻煩。

應用打包

應用開發完成後,需要打包成dmgexe等安裝檔案,可以使用electron-builder

electron-builder

electron-builder有很多配置選項,來呼叫各式各樣的程式打包。這裡只簡單介紹一下MacOS系統安裝程式和Windows系統NSIS安裝程式的打包配置(NSIS是一個開源的 Windows 系統下安裝程式製作工具)。

修改package.json,新增build配置:

{
  ...
  "homepage": "./", // 因為最後React應用引用的JS、CSS等資源都是本地的,只要用當前的相對路徑即可
  "build": {
    "appId": "com.xxx.app", // 應用ID
    "npmRebuild": true, // 打包前是否重新編譯NodeJS擴充套件
    "mac": {
      "category": "news", // 應用分類
      "icon": "build/icon.png" // 應用icon路徑
    },
    "win": {
      "icon": "build/icon.png", // 應用icon路徑
      "target": "nsis" // Windows安裝檔案的目標型別
    },
    "nsis": {
      "allowToChangeInstallationDirectory": true, // 是否允許修改安裝路徑
      "allowElevation": false, // 是否允許提升許可權
      "createDesktopShortcut": true, // 是否建立桌面快捷方式
      "menuCategory": true, //是否在選單欄建立分類
      "oneClick": false // 是否一鍵安裝
    },
    "files": [
      "build/**/*" // 引入的檔案
    ]
  }
  ...
}
複製程式碼

然後,就可以打包Electron應用了:

$ yarn react-scripts build // 先用webpack打包React應用到`build`目錄下
$ yarn eletron-builder // 再用eletron-builder打包Electron應用
複製程式碼

當然,正式打包還需要程式碼簽名,還有更多配置,請檢視electron-builder配置說明

參考

相關文章