Electron.js + React 实现跨平台方案
Electron.js 是使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。
Electron 压缩包下载
因为 electron 压缩包的服务器在国外,所以网速很慢而且不稳定,在下载之前把下载镜像的地址切换为淘宝的
npm config set ELECTRON_MIRROR https://npm.taobao.org/mirrors/electron/
Electron 打包 React 项目
1 安装 Electron
npm install -g electron
npm install -D electron
- 这里使用的是全局安装 electron,原因是因为 electron 包比较大,而且运行 electron 这一操作是可复用的,所以我认为全局安装 electron 更加合适。
2 相关配置
在根目录添加
main.js
文件// Modules to control application life and create native browser window const {app, BrowserWindow} = require('electron'); const path = require('path'); const url = require('url'); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow; function createWindow () { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), }, }); // 加载应用----适用于 react 项目 mainWindow.loadURL('http://localhost:3000/'); // 打开开发者工具,默认不打开 // mainWindow.webContents.openDevTools() // Open the DevTools. // mainWindow.webContents.openDevTools() // Emitted when the window is closed. mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null; }); } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', createWindow); // Quit when all windows are closed. app.on('window-all-closed', function () { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') app.quit(); }); app.on('activate', function () { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) createWindow(); }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here.
修改
package.json
配置将刚刚配置的
main.js
文件配置到package.json
的 “main”: “main.js”默认情况下,homepage 是 http://localhost:3000,build 后,所有资源文件路径都是 /static,而 Electron 调用的入口是 file: 协议,/static 就会定位到根目录去,所以找不到静态文件。在
package.json
文件中添加 homepage 字段并设置为”.”后,静态文件的路径就变成了相对路径,就能正确地找到了添加如下配置:“homepage”: “.”
配置
{ "name": "client", "version": "0.1.0", "private": true, "main": "main.js", "homepage": ".", "author": { "name": "Samuel Liu" }, "dependencies": { "antd": "^4.9.2", "electron": "^11.0.4", "electron-packager": "^15.2.0", "react": "^16.12.0", "react-dom": "^16.12.0", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "^3.3.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject", "electron-start": "electron .", "electron-build": "electron-packager ./build rui --win --out=release --arch=x64 --app-version=1.0.0 --electron-version=11.0.4" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "electron": "^11.0.4" } }
在根目录添加preload.js文件
// All of the Node.js APIs are available in the preload process. // It has the same sandbox as a Chrome extension. window.addEventListener('DOMContentLoaded', () => { const replaceText = (selector, text) => { const element = document.getElementById(selector); if (element) element.innerText = text; }; for (const type of ['chrome', 'node', 'electron']) { replaceText(`${type}-version`, process.versions[type]); } });
3 启动 Electron
# 启动react项目
npm start
# 启动electron
npm run electron-start
注意:启动 electron 应用后,如果无法显示 index 页面,可能是你路由配置了 BrowserRouter 模式,请改成 HashRouter。Vue 项目出不来的话,很大可能是使用了 history 路由模式,改成 hash 路由模式就可以了。
4 打包
注意:要修改跟目录下面的
main.js
文件// 加载应用----react 打包 mainWindow.loadURL(url.format({ pathname: path.join(__dirname, './build/index.html'), protocol: 'file:', slashes: true, })); // 加载应用----适用于 react 开发配置 // mainWindow.loadURL('http://localhost:3000/');
将你配置的
main.js
、package.json
、preload.js
,复制一份到 /public 静态文件中,不然打包后,还是会无法打开程序。
注意:修改 /public 中的main.js
pathname: path.join(__dirname, './index.html')
// 加载应用----react 打包 mainWindow.loadURL(url.format({ pathname: path.join(__dirname, './index.html'), protocol: 'file:', slashes: true, })); // 加载应用----适用于 react 开发配置 // mainWindow.loadURL('http://localhost:3000/');
安装 electron-packager
# 根目录下安装 electron-packager 包 npm install electron-packager --save-dev # 安装 electron-packager 命令 npm install electron-packager -g
electron-packager 命令介绍
electron-packager <location of project> <name of project> <platform> <architecture> <electron version> <optional options>
- location of project: 项目的本地地址,此处我这边是 ~/knownsec-fed
- location of project: 项目名称,此处是 knownsec-fed
- platform: 打包成的平台
- architecture: 使用 x86 还是 x64 还是两个架构都用
- electron version: electron 的版本
配置package.json打包脚本
“electron-build”: “electron-packager ./build rui –platform=win32 –arch=x64 –out=./../out –ar –app-version=0.0.1 –electron-version=6.0.1”,
开始打包
# 先编译出静态资源 npm run build # 再编译 electron npm run electron-build
找到打包文件中 exe 文件,双击打开运行
5 asar压缩
"electron-build": "electron-packager ./build rui --platform=win32 --arch=x64 --out=./../out --app-version=0.0.1 --asar --electron-version=6.0.1",
6 使用 inno 来编译打包好的文件
- 下载安装 Inno Setup
- 下载地址:https://pc.qq.com/detail/13/detail_1313.html