使用 Electron 和 React 創建應用程式
使用 create-react-app
建立 Electron Node.js 桌面應用程式的方法
2021 更新: 我強烈建議使用 electron-react-boilerplate
取代本文所述的方法
當我在 2015 年首次使用 Electron 時,它還不清楚它在現代應用程式中如此普及,而且我對其所導致的應用程式大小感到震驚。
但是,我們可以清楚地知道 Electron 已經成為必不可少的工具,並且你的應用程式不需要讓人感到遲鈍和消耗大量記憶體,就像VS Code每天向我展示的那樣(在一部不是非常快的機器上)。
所以,這裡有一個快速入門指南,使用 create-react-app
創建一個React應用程式,並預先整合了 ESlint。
如果尚未安裝 Node.js, 請先安裝
在 macOS 上:
轉到開發資料夾
建立 React 應用程式
1 2
| npx create-react-app app cd app
|
加入 Electron
1 2
| npm install electron npm install --save-dev electron-builder
|
安裝 foreman
以允許從命令列執行應用程式
安裝 create-react-app 的相依性
配置 eslint
.eslintrc.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| { "env": { "browser": true, "commonjs": true, "es6": true, "jest": true }, "parserOptions": { "ecmaFeatures": { "jsx": true }, "sourceType": "module" }, "rules": { "no-const-assign": "warn", "no-this-before-super": "warn", "no-undef": "warn", "no-continue": "off", "no-unreachable": "warn", "no-unused-vars": "warn", "constructor-super": "warn", "valid-typeof": "warn", "quotes": [ 2, "single" ], "semi": [ "error", "never" ] }, "parser": "babel-eslint", "extends": "airbnb", "plugins": [ "react", "jsx-a11y", "import" ] }
|
現在添加 ESLint 和一些其輔助工具
1
| npm install eslint eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react eslint-plugin-import
|
目前的檔結構如下所示:
現在調整 package.json
檔案以添加一些 Electron 輔助工具。
檔案內容目前類似於:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| { "name": "gitometer", "version": "0.1.0", "private": true, "dependencies": { "electron": "^1.7.5", "eslint": "^4.5.0", "eslint-config-airbnb": "^15.1.0", "eslint-plugin-import": "^2.7.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-react": "^7.3.0", "react": "^15.6.1", "react-dom": "^15.6.1", "react-scripts": "1.0.11" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": { "electron-builder": "^19.24.1" } }
|
(版本會在我發布後過時,所以不要在意)
將腳本屬性清除並改為
1 2 3 4 5 6 7 8 9 10 11 12
| "scripts": { "start": "nf start -p 3000", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject", "electron": "electron .", "electron-start": "node src/start-react", "react-start": "BROWSER=none react-scripts start", "pack": "build --dir", "dist": "npm run build && build", "postinstall": "install-app-deps" },
|
在 Windows 上,您可能需要在其中使用環境變數的 .env
文件中放置 BROWSER=none
,因為環境變數在 Linux/macOS 上無法正常工作
如您所見, start
已更改為 react-start
,但其餘部分保持不變,同時添加了一些 Electron 公用工具。
同樣地添加
1 2
| "homepage": "./", "main": "src/start.js",
|
和
1 2 3 4 5 6 7 8 9
| "build": { "appId": "com.electron.electron-with-create-react-app", "win": { "iconUrl": "https://cdn2.iconfinder.com/data/icons/designer-skills/128/react-256.png" }, "directories": { "buildResources": "public" } }
|
最終結果應如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| { "name": "gitometer", "version": "0.1.0", "private": true, "dependencies": { "electron": "^1.7.5", "eslint": "^4.5.0", "eslint-config-airbnb": "^15.1.0", "eslint-plugin-import": "^2.7.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-react": "^7.3.0", "react": "^15.6.1", "react-dom": "^15.6.1", "react-scripts": "1.0.11" }, "devDependencies": { "electron-builder": "^19.24.1" }, "homepage": "./", "main": "src/start.js", "scripts": { "start": "nf start -p 3000", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject", "electron": "electron .", "electron-start": "node src/start-react", "react-start": "BROWSER=none react-scripts start", "pack": "build --dir", "dist": "npm run build && build", "postinstall": "install-app-deps" }, "build": { "appId": "com.electron.electron-with-create-react-app", "win": { "iconUrl": "https://cdn2.iconfinder.com/data/icons/designer-skills/128/react-256.png" }, "directories": { "buildResources": "public" } } }
|
現在在專案根目錄中創建一個名為 Procfile
的文件,其內容如下:
1 2
| react: npm run react-start electron: npm run electron-start
|
配置完成!
現在讓我們開始編寫一些程式碼。
src/start.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| const { app, BrowserWindow } = require('electron')
const path = require('path') const url = require('url')
let mainWindow
function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } })
mainWindow.loadURL( process.env.ELECTRON_START_URL || url.format({ pathname: path.join(__dirname, '/../public/index.html'), protocol: 'file:', slashes: true }) )
mainWindow.on('closed', () => { mainWindow = null }) }
app.on('ready', createWindow)
app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } })
app.on('activate', () => { if (mainWindow === null) { createWindow() } })
|
src/start-react.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const net = require('net') const childProcess = require('child_process')
const port = process.env.PORT ? process.env.PORT - 100 : 3000
process.env.ELECTRON_START_URL = `http://localhost:${port}`
const client = new net.Socket()
let startedElectron = false const tryConnection = () => { client.connect({ port }, () => { client.end() if (!startedElectron) { console.log('starting electron') startedElectron = true const exec = childProcess.exec exec('npm run electron') } }) }
tryConnection()
client.on('error', () => { setTimeout(tryConnection, 1000) })
|
啟動
就是這樣!
執行
你應該會在原生應用程式中看到 React 範例應用程式:
感謝
本文受到 https://gist.github.com/matthewjberger/6f42452cb1a2253667942d333ff53404 的重要啟發。
tags: [“Electron”, “React”, “create-react-app”, “Node.js”]