如何使用 Electron 和 React 构建一个 APP
这篇文章主要记录了,使用 Electron 构建的一个 APP 过程的关键步骤和遇到的问题及解决方法。
最终成品效果图
起步
首先使用 create-react-app
新建一个 react app。因为这玩意儿新建的时候会帮你初始化npm
,相当刺激。
其实主要是使用create-react-app
的时候必须要指定一个名字。
然后他就在当前目录下创建了一个同名的文件夹,所有东西都放在这个文件夹下面了。(可能我没找到如何在当前目录创建的方法,欢迎指正)
1 | npx create-react-app test-app |
安装好以后,我们再按照 Electron 官方示例继续。
1 | npm install --save-dev electron |
然后。。。就卡住了,卡住了有木有?!是我们姿势不对么?这里什么也没写啊。什么鬼?
1 | > electron@1.8.4 postinstall /Users/godfery/GitRepo/hiyangguo.github.io/node_modules/electron |
那我们加个参数,看看到底是什么情况
1 | npm install --save-dev electron --verbose |
之后我们就能看到了,是在下载 electron 的地方,下载不下来,龟速,所以我们需要就使用国内的镜像。
在根目录新建一个
.npmrc
文件,内容如下:1 | ## 这里推荐使用淘宝镜像,当然也可以使用其他镜像 |
也可以使用声明临时变量的方式
1 | export electron_mirror="https://npm.taobao.org/mirrors/electron/" |
之后再执行npm install --save-dev electron
就可以顺利的安装了。
然后修改package.json
1 | { |
之后在根目录新建一个main.js
文件
1 | const { app, BrowserWindow } = require('electron') |
最后运行
1 | npm run start |
当当当当!
安装扩展
既然是用react
开发,肯定是要用React Developer Tools的,这里就来说一下,如何在electron
中使用拓展。(以 mac 为例)
- 打开 Chrome 浏览器,导航到
chrome://extensions
,找到 React Developer Tools 插件的 ID:fmkadmapgofadopljbjfkapdkoienihi - 进入
~/Library/Application Support/Google/Chrome/Default/Extensions
目录。在 Finder 中,点击 前往 > 前往文件夹。(或使用快捷键shift + command + G
)。粘贴即可。 - 进入
fmkadmapgofadopljbjfkapdkoienihi
文件夹,子目录3.2.1_0
(也可能是其他的,反正是个版本号)中的的文件拷贝项目根目录下chrome-extensions
目录中,并重命名为react-dev-tools
。 - 修改代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53const { app, BrowserWindow } = require('electron')
+ const path = require('path')
// 保持一个对于 window 对象的全局引用,如果你不这样做,
// 当 JavaScript 对象被垃圾回收, window 会被自动地关闭
let win
function createWindow() {
+ installExtensions()
// 创建浏览器窗口。
win = new BrowserWindow({ width: 800, height: 600 })
// 然后加载应用的 index.html。
win.loadURL('http://localhost:3000')
// 打开开发者工具。
win.webContents.openDevTools()
// 当 window 被关闭,这个事件会被触发。
win.on('closed', () => {
// 取消引用 window 对象,如果你的应用支持多窗口的话,
// 通常会把多个 window 对象存放在一个数组里面,
// 与此同时,你应该删除相应的元素。
win = null
})
}
// Electron 会在初始化后并准备
// 创建浏览器窗口时,调用这个函数。
// 部分 API 在 ready 事件触发后才能使用。
app.on('ready', createWindow)
// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
// 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
// 否则绝大部分应用及其菜单栏会保持激活。
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// 在macOS上,当单击dock图标并且没有其他窗口打开时,
// 通常在应用程序中重新创建一个窗口。
if (win === null) {
createWindow()
}
})
+ function installExtensions() {
+ BrowserWindow.addDevToolsExtension(path.join(__dirname, 'chrome-extensions', 'react-dev-tools'));
+ }
之后重启 electron
create-react-app 使用 less
方法一
大致是说:
- 安装 less
- 使用 less 编译
- 添加 watch 监控文件变更实时编译
- 引入最终编译的 css 文件
妈耶,简直 low 到爆啊。
方法二
运行 npm run eject
,然后改 webpack 的 config 。这方法破坏了整个项目,简直了。也不推荐。
方法三
那就没有什么既不破坏项目,又可以方便的使用 less 的方法呢?当然有
使用 react-app-rewired 即可,方便简单的扩展 create-react-app
- 安装 react-app-rewired
1
npm install react-app-rewired react-app-rewire-less --save-dev
- 在根目录创建
config-overrides.js
文件。1
2
3
4
5const rewireLess = require('react-app-rewire-less');
module.exports = function override(config, env) {
config = rewireLess(config, env);
return config;
}; - 将
packge.json
中所有的react-scripts
换成react-app-rewired
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26{
"name": "test-app",
"version": "0.1.0",
"main": "main.js",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1"
},
"scripts": {
"start-electron": "electron .",
- "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",
- "eject": "react-scripts eject"
},
"devDependencies": {
"electron": "^1.8.4",
"react-app-rewire-less": "^2.1.1",
"react-app-rewired": "^1.5.0"
}
} - 运行
npm run start
electron 跨域
electron 可以禁用跨域检查
1 | win = new BrowserWindow({ |
开发过程不再赘述,有兴趣可以直接查看源码。后续会单开一篇文章详细讲解开发过程以及如何更好的发挥 electron 的优势。
打包
修改 electron 代码
修改package.json
中的 script
, 添加NODE_ENV
环境变量用于区分环境
1 | - "start-electron": "electron .", |
然后修改
main.js
1 | const { app, BrowserWindow } = require('electron') |
打包
由于 create-react-app
默认打包的路径为 /
根目录,而在 electron 中,需要使用相对路径所以需要再次次改package.json
1 | { |
打包工具这里使用的是electron-builder。
操作步骤
- 安装
electron-builder
1
npm install electron-builder --save-dev
- 修改配置,添加必要的文件。
- 修改
name
,verison
,description
,author
字段 - 在
./public
文件夹中放入icon.png
文件 - 将
main.js
重命名为electron.js
,让如根目录./public
目录下。同时修改package.json
- 由于
electron-builder
中不能使用dependencies
,所以务必将所有的dependencies
加入devDependencies
。
最终的package.json
文件:
- 修改
1 | { |
之后运行npm run packager
即可得到 dmg
安装文件。
参考文章
From React to an Electron app ready for production
如何加载一个开发者工具扩展
Electron 官放文档