electron+react+mysql快速构建桌面应用程序
electron+react+mysql快速构建桌面应用程序
在electron中创建react项目
创建react项目
npx create-react-app electron-react-ipc-app
安装electron相关模块
npm install electron electron-builder wait-on
npm install electron-is-dev concurrently
electron-builder:用于为 macOS、Windows 和 Linux 打包和构建准备好分发的 Electron 应用程序,并提供开箱即用的“自动更新”支持。
wait-on:用于等待资源的简单命令行实用程序和 Node.js API,确保开发环境下electron能够访问到react服务。
electron-is-dev:仅在开发期间用于启用调试功能。 这个包必须在 Electron 主进程中使用。
concurrently:同时运行多个命令。像 npm run watch-js 和 npm run watch-less 但更好。
创建electron文件夹和main.js
const {app, BrowserWindow} = require('electron');
const isDev = require('electron-is-dev');
const path = require('path');
let win ;
function createWindow() {
win = new BrowserWindow({
width:800,
height:600,
});
// const startURL = isDev ? 'http://localhost:3000' :
// `file://${path.join(__dirname, '../build/index.html')}`;
// win.loadURL(startURL); //npm run dev
const startURL = `file://${path.join(__dirname, '../build/index.html')}`;//npm run estart
win.loadURL(startURL);
// Open the DevTools.
if (isDev) {
win.webContents.openDevTools({ mode: 'detach' });
}
}
app.whenReady().then(()=> {
createWindow();
})
app.on('window-all-closed', (e) => {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
修改package.json
添加main属性指向electron的启动js及项目主页的url
"main": "electron/main.js",
"homepage": "./",
添加electron启动和打包脚本
"dev": "concurrently \"npm start\" \"wait-on http://localhost:3000 && electron .\"",
"ebuild": "npm run build && electron-builder",
"estart": "npm run build && electron ."
防止electron打包报错
-
添加devDependencies属性,并将dependencies属性中的electron和electron-builder移动到devDependencies中。
-
electron-builder打包默认是去找 public/electron.js,如果想把electron代码放在别处(如electron/main.js),则需要在package.js中添加如下配置,它指定了electron-builder打包文件及额外的配置文件(main的路径),然后将react和electron的清单文件分离。
"build": { "files": [ "build/**/*", "node_modules/**/*", "electron/**/*" ], "directories":{ "buildResources": "assets" }, "extraMetadata": { "main": "electron/main.js" } }
修改后的package.json如下:
{
"name": "electron-react-ipc-app",
"main": "electron/main.js",
"homepage": "./",
"description":"test",
"author":"test",
"version": "0.1.0",
"private": true,
"devDependencies": {
"electron": "^22.0.0",
"electron-builder": "^23.6.0"
},
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"concurrently": "^7.6.0",
"electron-is-dev": "^2.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"wait-on": "^7.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"dev": "concurrently \"npm start\" \"wait-on http://10.10.10.5:3000 && electron .\"",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"ebuild": "npm run build && electron-builder",
"estart": "npm run build && electron ."
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"build": {
"files": [
"build/**/*",
"node_modules/**/*",
"electron/**/*"
],
"directories":{
"buildResources": "assets"
},
"extraMetadata": {
"main": "electron/main.js"
}
}
}
创建.env文件
BROWSER=none (避免react服务启动时打开浏览器)
此时electron-react的目录结构

启动electron
npm run dev (会先启动react服务,再启动electron服务访问localhost:4000)
npm run ebuild(会先打包react项目,再打包electron)
npm run estart(会先打包react项目,再启动electron访问react打包后的静态文件)
安装mysql2模块
electron可以通过安装mysql2模块,建立连接并访问数据库,还可以创建数据库连接池。
npm install mysql2
测试安装
测试代码
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123456',
port: '3306',
database: 'test'
});
connection.connect();
var sql = 'SELECT * FROM material';
connection.query(sql,function (err, result) {
if(err){
console.log('[SELECT ERROR] - ',err.message);
return;
}
console.log(result);
});
connection.end();
控制台输入 node .\electron\connection.js

接着将connection引入到electron中即可完成增删改查操作。
利用IPC模块完成数据交互
现在通过electron可以访问数据库数据,可以通过electron的IPC(进程间通信)模块完成数据交互和渲染。在react项目利用Elctron的ipcRenderer.invoke()函数从渲染器请求主进程数据,主进程通过ipcMain.handle()函数监听渲染器请求数据完成数据交互。这里访问数据库直接采用 mysql2/promise 模块。
创建预加载文件preload.js
为了安全起见,electron主进程不会直接暴露整个 ipcRenderer.invoke API。 确保尽可能限制渲染器对 Electron API 的访问。
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI',{
findAll: () => ipcRenderer.invoke('findAll')
})
修改main.js
main.js中指定预加载文件路径
win = new BrowserWindow({
width:800,
height:600,
//指定预加载文件的路径
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
main.js中添加ipcMain.handle()监听事件
ipcMain.handle('findAll', async() => {
var sql = 'SELECT * FROM material';
var [rows,fields] = await connection.query(sql);
return rows;
})
react代码中调用electron API
function App() {
const [result,setResult] = useState('');
const handleClick = async () => {
const a = await window.electronAPI.findAll();
console.log(a)
setResult(JSON.stringify(a))
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<button onClick={handleClick}>发送请求</button>
<textarea value={result}/>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
运行效果
