使用 create-react-app
建立 Electron Node.js 桌面應用程式的方法
2021 更新: 我強烈建議使用
electron-react-boilerplate
取代本文所述的方法
- 如果尚未安裝 Node.js,請先安裝
- 轉到開發資料夾
- 建立 React 應用程式
- 加入 Electron
- 安裝
foreman
以允許從命令列執行應用程式 - 安裝 create-react-app 的相依性
- 配置 eslint
- 配置完成!
- 啟動
- 感謝
當我在 2015 年首次使用 Electron 時,它還不清楚它在現代應用程式中如此普及,而且我對其所導致的應用程式大小感到震驚。
但是,我們可以清楚地知道 Electron 已經成為必不可少的工具,並且你的應用程式不需要讓人感到遲鈍和消耗大量記憶體,就像VS Code每天向我展示的那樣(在一部不是非常快的機器上)。
所以,這裡有一個快速入門指南,使用 create-react-app
創建一個React應用程式,並預先整合了 ESlint。
如果尚未安裝 Node.js, 請先安裝
在 macOS 上:
brew install node
轉到開發資料夾
cd ~/dev
建立 React 應用程式
npx create-react-app app
cd app
加入 Electron
npm install electron
npm install --save-dev electron-builder
安裝 foreman
以允許從命令列執行應用程式
npm install foreman -g
安裝 create-react-app 的相依性
npm install
配置 eslint
.eslintrc.json
{
"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 和一些其輔助工具
npm install eslint eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react eslint-plugin-import
目前的檔結構如下所示:
現在調整 package.json
檔案以添加一些 Electron 輔助工具。
檔案內容目前類似於:
{
"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"
}
}
(版本會在我發布後過時,所以不要在意)
將腳本屬性清除並改為
"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 公用工具。
同樣地添加
"homepage": "./",
"main": "src/start.js",
和
"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"
}
}
最終結果應如下所示:
{
"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
的文件,其內容如下:
react: npm run react-start
electron: npm run electron-start
配置完成!
現在讓我們開始編寫一些程式碼。
src/start.js
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
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)
})
啟動
就是這樣!
執行
npm start
你應該會在原生應用程式中看到 React 範例應用程式:
感謝
本文受到 https://gist.github.com/matthewjberger/6f42452cb1a2253667942d333ff53404 的重要啟發。