# electron-react **Repository Path**: oscube/electron-react ## Basic Information - **Project Name**: electron-react - **Description**: electron + react - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-11-10 - **Last Updated**: 2023-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Electron + React ### 配置开发环境 1. 创建react项目 > npx create-react-app [xxx] 2. 安装electron依赖 > tyarn add electron --dev > tyarn add electron-is-dev 3. 在项目根目录下创建main.js文件以及在package.json中配置mian入口 ``` // --- main.js --- const {app, BrowserWindow} = require('electron'); const isDev = require('electron-is-dev') var mainWindow; app.on('ready', () => { mainWindow = new BrowserWindow({ width: 1280, height: 680, webPreferences: { // 允许渲染进程使用nodejs nodeIntegration: true, contextIsolation: false } }) const urlLocation = isDev ? 'http://localhost:3000' : '' mainWindow.loadURL(urlLocation) // 打开开发工具 // mainWindow.webContents.openDevTools() }) // --- package.json --- { ... "main": "main.js", ... } ``` 4. 安装脚手架,便于开发调试 > tyarn add concurrently wait-on cross-env nodemon --dev 5. package.json中添加script脚本 ``` "dev": "concurrently \"wait-on http://localhost:3000 && nodemon --watch main.js --exec electron .\" \"cross-env BROWSER=none npm start\"" ``` > **脚本解释**:等待localhost:3000服务启动后再打开electron应用程序,并添加监听main.js文件发生变化后自动刷新electron;"cross-env BROWSER=none npm start"表示启动服务默认不打开浏览器 ### 在react中使用nodejs 在引入fs、path等node模块时,需要在前面加上window > const fs = window.require('fs') ### 在渲染进程中使用electron 1. 安装@electron/remote > tyarn add @electron/remote 2. 代码配置 ``` // --- 在main.js中加入远程配置支持 --- const remote = require("@electron/remote/main") remote.initialize() ... remote.enable(mainWindow.webContents) // --- mian.js完整示例 --- const {app, BrowserWindow} = require('electron'); const isDev = require('electron-is-dev') const path = require('path') // 加入远程配置支持 const remote = require("@electron/remote/main") remote.initialize() const createWindow = () => { const mainWindow = new BrowserWindow({ title: 'Electron + React', width: 1280, height: 680, webPreferences: { // 允许渲染进程使用nodejs nodeIntegration: true, contextIsolation: false } }) mainWindow.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, './build/index.html')}`) // 加入远程配置支持 remote.enable(mainWindow.webContents) // 打开开发工具 // mainWindow.webContents.openDevTools() } app.whenReady().then(() => { createWindow() app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) ``` ### 读取本地文件 1. 使用fs读取本地图片并转换为base64编码格式 ``` const fs = window.require('fs').promises fs.readFile(path).then(function(data, err) { const base64Str = `data:image/*;base64,${data.toString('base64')}` document.getElementById('image').src = base64Str }) ``` 2. 使用fs读取本地文本并转换为utf8编码格式 ``` const fs = window.require('fs').promises fs.readFile(path).then(function(data, err) { document.getElementById('txt').innerText = data.toString('utf8') }) ``` ### 主进程和渲染进程进行通信 使用ipcMain、ipcRenderer进行事件传递 ``` // --- reactjs渲染引入方式,注意需要加上window --- const { ipcRenderer } = window.require('electron') // --- js渲染引入方式 --- const { ipcRenderer } = require('electron') // --- electron 主进程 --- const { ipcMain } = require('electron') ipcMain.on('newWindow', (event, args) => { ... }) ``` ### Electron编译打包 1. 安装 electron-builder 脚手架 > tyarn add electron-builder --dev 2. 补充完善package.json配置,对应内容根据自身情况修改 ``` { ... "description": "Electron add React", "author": { "name": "Incosw", "email": "1099209211@qq.com" }, "repository": "https://gitee.com/oscube/electron-react.git", "homepage": "./", "build": { "appId": "electronReact", "productName": "Electron + React应用示例", "copyright": "Copyright © 2022 ${author}", "files": [ "build/**/*", "node_modules/**/*", "package.json", "main.js" ], "directories": { "buildResources": "assets" }, "extends": null, "mac": { "category": "public.app-category.business", "artifactName": "${productName}-${version}-${arch}.${ext}" }, "dmg": { "icon": "assets/icon.icns", "iconSize": 100, "contents": [ { "x": 380, "y": 280, "type": "link", "path": "/Applications" }, { "x": 110, "y": 280, "type": "file" } ], "window": { "width": 500, "height": 500 } }, "win": { "target": [ "msi", "nsis" ], "icon": "assets/icon.ico", "artifactName": "${productName}-Setup-${version}.${ext}", "publisherName": "Incosw" }, "nsis": { "allowToChangeInstallationDirectory": true, "oneClick": false, "perMachine": false } }, ... } ``` > **files**:在electron-builder打包的时候会自动忽略掉一些不需要的文件,而此时这些文件却是应用需要用到的文件,就需要在这里进行配置,添加上后就不会被builder打包过滤掉。 > **buildResources**:指定编译打包需要用到的资源存放位置 > **category**:指定mac应用分类,具体类型可查阅官方文档:https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8 > **dmg**:设置mac安装包窗口以及程序图标等属性,具体说明可查阅官方文档:https://www.electron.build/configuration/dmg > **win**:设置windows安装包以及程序图标等属性,具体说明可查阅官方文档:https://www.electron.build/configuration/win > **nsis**:设置windows安装包程序属性,具体说明可查阅官方文档:https://www.electron.build/configuration/nsis 3. 在scripts中添加脚本执行命令 ``` { ... "scripts": { ... "pack": "electron-builder --dir", "dist": "electron-builder", "prepack": "npm run build", "predist": "npm run build" } ... } ``` > **脚本说明**:pack表示打包出来的文件为已经安装完的应用程序;dist表示打包成安装包,例如:windows的nsis安装文件,mac的dmg安装文件;prepack/predist钩子可以根据自身情况去除或添加上,此处表示在执行pack/dist打包命令前先执行prepack/predist ### 深度优化打包体积 1. 在项目根目录下创建 webpack.config.js,并拷贝以下代码 ``` const path = require('path') module.exports = { target: 'electron-main', entry: './main.js', output: { path: path.resolve(__dirname, './build'), filename: 'main.js' }, node: { __dirname: false } } ``` 2. 修改package.json ``` { "scripts": { // 添加scripts脚本执行命令 "buildMain": "webpack", // 修改prepack、predist命令 "prepack": "npm run build && npm run buildMain", "predist": "npm run build && npm run buildMain" }, "build": { ··· // 添加指令打包后main.js入口指向的路径 "extraMetadata": { "main": "./build/main.js" }, ··· } } ``` 3. 修改mian.js ``` - mainWindow.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, './build/index.html')}`) + mainWindow.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, './index.html')}`) ``` > **优化说明**:package.json中基本上可以把大多数依赖以及脚手架从dependencies转移到devDependencies中了,具体根据自身使用情况而定。 ### 自动发布GitHub平台 1. 首先需要在github上创建私人令牌Token,具体网址:https://github.com/settings/tokens/new 2. 在package.json中加入以下代码 ``` { ··· // github仓库地址 "repository": "https://github.com/oscube/electron-react.git", "scripts": { ··· // 执行发布脚本,需要替换成自己的Token "release": "cross-env GH_TOKEN=[token] electron-builder", "prerelease": "npm run build && npm run buildMain" } "build": { ··· // 指定发布平台 "publish": ["github"], ··· } ··· } ``` ### 自动更新 1. 安装electron-updater > tyarn add electron-updater --dev 2. 在mian.js中加入以下代码 ``` const { autoUpdater } = require('electron-updater') ··· app.whenReady().then(() => { autoUpdater.audoDownload = false autoUpdater.checkForUpdatesAndNotify() autoUpdater.on('error', (error) => { // dialog.showErrorBox('Error:', error === null ? 'unknown' : (error.stac)) }) autoUpdater.on('update-available', () => { dialog.showMessageBox({ type: 'info', title: '应用有新的版本', message: '发现新版本,是否现在更新?', buttons: ['是', '否'] }, (buttonIndex) => { if (buttonIndex === 0) { autoUpdater.downloadUpdate() } }) }) autoUpdater.on('update-available', () => { // 没有新版本,当前已经是最新版本 }) }) ``` > 了解更多方法请查阅官方文档:https://www.electron.build/auto-update.html