Electron 的官方文档给我一种错综复杂的感觉,而官方给的 starter 又过于简单,所以如何引入 React 并实现完善的打包机制对于萌新来说也是非常困难的 ?,所以本人根据自己踩过的坑,综合下来,写了本教程,希望看过后大家都能有所收获。
适用人群
此教程适用于了解 React,想要学习 Electron,但是不知如何将 React 添加至 Electron 中的同学。
文章结构
一、基于 React 初始化项目
1. 初始化
首先利用 facebook 官方的create-react-app
创建一个基础项目。你可以根据你平时喜欢的包管理工具安装:
# npx
npx create-react-app react-electron-demo
# npm
npm init react-app react-electron-demo
# yarn
yarn create react-app react-electron-demo
复制代码
安装完成后,项目的目录如下:
react-electron-demo
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ └── registerServiceWorker.js
└── yarn.lock
复制代码
2. 删除 ServiceWorker 和 manifest.json
因为Electron
打包后读取的页面为本地静态资源,所以不需要ServiceWorker
和manifest.json
,这两个东西的作用可以自行 google。具体操作如下:
-
删除
public/manifest.json
文件。 -
删除
public/index.html
文件的以下代码:
/* public/index.html:11行 */
- <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
复制代码
- 删除
src/registerServiceWorker.js
。 - 删除
src/index.js
的以下内容:
/* src/index.js:5行和7行 */
- import registerServiceWorker from './registerServiceWorker';
- registerServiceWorker();
复制代码
3.使用react-app-rewired
通过使用
react-app-rewired
,我们可以在不eject
项目的情况下,自定义 webpack 配置等。
- (1) 安装
# npm
npm install react-app-rewired --save-dev
# yarn
yarn add -D react-app-rewired
复制代码
- (2) 根目录下创建
config-overrides.js
文件,文件内容如下:
module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
};
复制代码
- (3) 更改
package.json
配置,变化如下:
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom"
}
复制代码
- (4) 启动项目、打包
# 运行dev
npm run start
# 打包
npm run build
复制代码
二、添加Electron
1.添加Electron
入口文件
- (1) 新建
app/index.js
,文件内容如下:
const { app, BrowserWindow } = require('electron');
let win;
function createWindow() {
// 创建浏览器窗口。
win = new BrowserWindow({ width: 800, height: 600 });
// 然后加载应用的 index.html。
win.loadURL('http://localhost:3000');
// 当 window 被关闭,这个事件会被触发。
win.on('closed', () => {
win = null;
});
}
app.on('ready', createWindow);
// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (win === null) {
createWindow();
}
});
复制代码
-
(2) 在
package.json
中添加"main": "app/index.js"
,表示Electron
应用的入口路径。 -
(3) 添加
Electron
启动命令,并安装Electron
依赖。
npm install --save-dev electron
复制代码
/* package.json */
"scripts": {
+ "start:electron": "electron app"
}
复制代码
- (4) 输入
npm run start:electron
,一个开发环境下的Electron
应用就启动了。
2.优化 Electron 启动
现在如果要启动开发模式,需要启动两个命令,即
npm run start
和npm run start:electron
,那如何才能一个命令就启动呢?
- 我们需要使用到
concurrently
来同时运行两个命令 - 如果要让
react-app-rewired start
运行时,不打开浏览器,需要传入BROWSER=none
,所以也需要安装cross-env
做传值兼容。 - 因为同时运行时,
Electron
打开时,服务器还没运行好,所以需要使用wait-on
npm install --save-dev concurrently cross-env wait-on
复制代码
添加package.json
中的启动命令。
/* package.json */
"script": {
- "start": "react-app-rewired start",
+ "start": "concurrently \"npm run start:react\" \"npm run start:electron\"",
+ "start:react": "cross-env BROWSER=none react-app-rewired start",
- "start:electron": "electron app",
+ "start:electron": "wait-on http://localhost:3000 && electron app",
}
复制代码
通过
npm run start
3.添加调试工具
调试工具大致需要 Electron 和 React 调试两种。
添加如下代码,添加 React 相关的Chrome
插件,并安装Devtron
,用于调试 Electron 进程通信等;添加electron-is-dev
,用于识别当前 Electron 是开发环境还是打包环境。
- 安装需要使用的依赖。
npm install --save-dev electron-devtools-installer \
electron-debug \
devtron \
npm install --save electron-is-dev
复制代码
- 在代码中添加开发工具。
/* app/index.js */
const isDev = require('electron-is-dev');
// 利用electron-debug,添加和Chrome类似的快捷键
isDev && require('electron-debug')({ enabled: true, showDevTools: false });
// 用于添加Chromium插件
function createDevTools() {
const {
default: installExtension,
REACT_DEVELOPER_TOOLS,
REDUX_DEVTOOLS,
} = require('electron-devtools-installer');
// 安装devtron
const devtronExtension = require('devtron');
devtronExtension.install();
// 安装React开发者工具
installExtension(REACT_DEVELOPER_TOOLS);
installExtension(REDUX_DEVTOOLS);
}
// 修改应用启动事件
app.on('ready', () => {
createWindow();
// 只在开发环境加载开发者工具
isDev && createDevTools();
});
复制代码
安装完毕后,运行
npm run start
,通过Command + Option + I
(Windows为F12
)就可以启动开发者工具,然后在扩展中就可以查看到React
和Redux
的开发者工具了。
现在基本的开发配置已经搭好,接下来让我们看一下如何配置打包功能。
三、打包
1.安装依赖
- 打包时,我们需要先安装依赖,我们使用的是
electron-builder
进行打包,执行以下命令进行安装。
npm install --save-dev electron-builder
复制代码
2.打包流程及配置
- 打包的基本流程为:
- 打包
React
至build
目录下 - 拷贝
Electron
代码至build
目录下 - 使用
electron-builder
进行打包
- 打包
根据以上流程,添加对应的打包命令。
/* package.json */
{
"scripts": {
- "build": "react-app-rewired build",
+ "build": "npm run build:copy && npm run pack",
+ "build:react": "react-app-rewired build",
+ "build:copy": "npm run build:react && npm run copy:electron",
+ "pack": "electron-builder",
+ "copy:electron": "cp -r ./app/. ./build"
}
}
复制代码
因为 Electron 是访问本地的文件,所以需要将 Webpack 的 output.publicPath
设置为 ./
。需要做以下修改:
/* config-overrides.js */
module.exports = function override(config, env) {
//do stuff with the webpack config...
+ if (env === "production") {
+ config.output.publicPath = './';
+ }
return config;
};
复制代码
在根目录下创建icons
文件夹,用于存放应用logo
,我在网上找了一个,也就是文件夹内的icon.png
和icon.icns
。然后在package.json
中添加一些配置信息。
{
"build": {
"productName": "Electron-React-Test",
"extends": null,
"files": ["build/**/*"],
"mac": {
"icon": "icons/icon.icns"
},
"win": {
"target": "nsis",
"icon": "icons/icon.png"
},
"linux": {
"target": ["AppImage", "deb"],
"icon": "icons/icon.png"
},
"extraMetadata": {
"main": "build/index.js"
},
"directories": {
"buildResources": "assets"
}
}
}
复制代码
3.修改 Electron 入口文件
- 添加打包环境下,访问的
URL
地址。
const isDev = require('electron-is-dev');
const path = require('path');
const devUrl = 'http://localhost:3000';
// 本地文件路径定位到打包的react文件
const localUrl = `file://${path.resolve(
__dirname,
'../../app.asar/build'
)}/index.html`;
const appUrl = isDev ? devUrl : localUrl;
function createWindow() {
win = new BrowserWindow({ width: 800, height: 600 });
// 然后加载应用的地址
win.loadURL(appUrl);
win.on('closed', () => {
win = null;
});
}
复制代码
4.添加 Windows 系统打包配置
如果需要增加Windows
系统的打包文件,需要在package.json
中加入以下代码:
/* package.json */
{
"scripts": {
+ "build:win": "npm run build:react-copy && npm run pack:win",
+ "pack:win": "electron-builder --win",
}
}
复制代码
然后运行npm run build:win
即可。
结语
经过以上步骤,我们已经得到了一个可以打包的基础项目。源码详见react-electron-demo项目。