目录
-
Electron简介
- 打造你第一个 Electron 应用
- 下一步
-
整合
- create-react-app创建工程
- 整合antd
- 修改package.json
- config-overrides.js
- src/App.js
- 运行
- 整合Electron
- 安装Electron库
- 添加Electron启动文件
- 配置Electron入口
- 修改界面
- 调试运行
- 生产环境运行
-
分发应用
- 简介
- electron-builder 生成安装包
- 安装electron-builder
- 配置icon
- 配置package.json
- 生成安装包
参考文档
Electron简介
Electron是一个利用javascript/css/html来开发跨平台(Mac/Windows/Linux)桌面应用的框架。
VS Code/Atom/GitHub Desktop等软件是基于Electron编写的。
# 可以简单这样理解
Electron = nodejs + chrome内核
- 因为内置一个chrome内核,所以开发者可以使用javascript/html/css来构建界面;这一部分运行在
渲染进程
中。 - 因为内置nodejs环境,所以可以访问计算机本地的资源:读写磁盘文件、创建进程、本地通知、、、;这一部分运行在
主进程
中。
打造你第一个 Electron 应用
下一步
Electron
并没有限制我们使用什么技术/框架来渲染UI,我们希望结合Electron
+create-react-app
+redux
+react router
+antd
共同打造一个高效、快速的、工程化的开发体验。
整合
完整的示例可从这里下载
create-react-app创建工程
# 使用create-react-app创建工程
$ create-react-app demo-app
整合antd
# 添加antd库
$ yarn add and
# 这个库可以让我们不必运行CRA的eject
$ yarn add react-app-rewired --dev
# 按需加载
$ yarn add babel-plugin-import --dev
修改package.json
# 修改 start/build/test 脚本
...
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
}
...
config-overrides.js
在项目的根目录下增加一个config-overrides.js文件
const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
config = injectBabelPlugin(['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }], config);
return config;
};
src/App.js
import React, { Component } from 'react';
import { Button } from 'antd';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
}
}
export default App;
运行
# 调试运行,访问:http://localhost:3000/
$ npm start
# 生成release包
$ npm build
整合Electron
安装Electron库
# 安装electron
$ yarn add electron --dev
添加Electron启动文件
添加public/electron.js
// `主进程`入口
const electron = require('electron');
const platform = require('os').platform(); // 获取平台:https://nodejs.org/api/os.html#os_os_platform
// 控制app生命周期.
const app = electron.app;
// 浏览器窗口.
const BrowserWindow = electron.BrowserWindow;
const path = require('path');
const url = require('url');
console.log(platform);
// 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()
{
// 创建一个浏览器窗口.
mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: {
webSecurity: false, // 这样可以在 webview 中加载/显示本地计算机的图片。
} });
// 这里要注意一下,这里是让浏览器窗口加载网页。
// 如果是开发环境,则url为http://localhost:3000(package.json中配置)
// 如果是生产环境,则url为build/index.html
const startUrl = process.env.ELECTRON_START_URL || url.format({
pathname: path.join(__dirname, '/../build/index.html'),
protocol: 'file:',
slashes: true
});
// 加载网页之后,会创建`渲染进程`
mainWindow.loadURL(startUrl);
// 打开chrome浏览器开发者工具.
if(startUrl.startsWith('http'))
{
mainWindow.webContents.openDevTools();
// 加载 react/redux 调试工具(如果有需要的话)
if('darwin' === platform)
{
BrowserWindow.addDevToolsExtension('/Users/issuser/Library/Application\ Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/3.1.0_0');
BrowserWindow.addDevToolsExtension('/Users/issuser/Library/Application\ Support/Google/Chrome/Default/Extensions/lmhkpmbekcpmknklioeibfkpmmfibljd/2.15.2_0');
}
}
// Emitted when the window is closed.
mainWindow.on('closed', function () {
mainWindow = null
});
}
app.on('ready', createWindow);
app.on('window-all-closed', function () {
if (process.platform !== 'darwin')
{
app.quit();
}
});
app.on('activate', function ()
{
if (mainWindow === null)
{
createWindow();
}
});
// 这是一个示例,展示了`渲染进程`发送了`chooseFolder `事件后,`主进程`打开选择目录的对话框。
electron.ipcMain.on('chooseFolder', function(){
const dialog = electron.dialog;
dialog.showOpenDialog(mainWindow, {
properties: ['openDirectory']
});
});
配置Electron入口
package.json
文件
{
...
"main": "public/electron.js",
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"electron": "electron .",
"electron-dev": "ELECTRON_START_URL=http://localhost:3000 electron ."
},
...
}
修改界面
// src/App.js
// UI界面运行在`渲染进程`
import React, { Component } from 'react';
import { Button } from 'antd';
import './App.css';
// 渲染进程可以通过`ipcRenderer`向主进程发送消息。
const electron = window.require('electron');
const fs = electron.remote.require('fs');
const ipcRenderer = electron.ipcRenderer;
class App extends Component {
render() {
return (
<div className="App">
<Button type="primary" onClick={this.showNativeDialog}>Button</Button>
</div>
);
}
showNativeDialog() {
// 选择文件示例
// const dialog = electron.remote.dialog;
// dialog.showOpenDialog({
// properties: ['openDirectory']
// }, (filePaths)=>{
// console.log(filePaths);
// });
ipcRenderer.send('chooseFolder');
}
}
export default App;
调试运行
# 调试运行web程序
$ npm start
# 调试运行electron,并用浏览器窗口(BrowserWindow)加载上面的web程序
$ npm run electron-dev
生产环境运行
# 编译生成web页面的release包,结果保存在build目录
$ npm run build
# 运行electron,并用浏览器窗口(BrowserWindow)加载build/index.html文件
$ npm run electron
分发应用
简介
我们希望将Electron的app打包成.app/.exe发布给其他人下载安装。
分发的方式有好几种:
- 可以通过第三方
- 也可以下载Electron官方提供的壳子app,然后把package.json/build目录/public目录放到壳子对应的目录下即可
详情见官网指南分发应用
electron-builder生成安装包
安装electron-builder
$ npm install electron-builder --save-dev
配置icon
放在public/icon.png
,尺寸:512x512
配置package.json
{
"name": "demo-app",
// 配置app的名称
"productName": "示例",
"description": "描述信息",
"author": "作者",
"version": "0.1.0",
"private": true,
// 入口
"main": "./public/electron.js",
"homepage": "./",
// 把dependencies里面的内容都放到devDependencies里面去
"dependencies": {},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-scripts eject",
"electron": "electron .",
"electron-dev": "ELECTRON_START_URL=http://localhost:3000 electron .",
"packager": "npm run build && rm -rf dist && electron-builder"
},
"build": {
"appId": "com.isoftstone.apptools",
"mac": {
"category": "public.app-category.developer-tools"
},
"files": [
{
"from": "./",
"to": "./",
"filter": [
"**/*",
"!node_modules"
]
},
{
"from": "./node_modules/image-size",
"to": "./node_modules/image-size"
}
],
"directories": {
"buildResources": "public"
}
},
"devDependencies": {
"antd": "^3.3.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1",
"babel-plugin-import": "^1.6.6",
"electron": "^1.8.3",
"electron-builder": "^20.8.1",
"electron-load-devtool": "^1.0.0",
"image-size": "^0.6.2", // 这是一个第三方node模块
"react-app-rewired": "^1.5.0"
}
}
生成安装包
$ npm run packager