使用Electron开发一个文件上传小工具实践
ID: 符合预期的CoyPan
CoyPan,BAT某厂符合预期的FE,正努力成为一名出色的工程师
写在前面
Electron支持我们使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。也就是说,前端工程师也可以利用自己熟悉的技术栈,开发桌面应用。著名的VS Code 是基于 Electron 进行开发的。本文将简单介绍一些利用Electron开发一个文件上传小工具的实践。
搭建开发环境
Electron 基于 Node.js(作为后端运行时)和 Chromium(作为前端渲染)。搭建开发环境比较简单,保证本地有Node环境即可。然后依次执行以下命令:
# 初始化项目
$ npm init
# 安装electron
$ npm install --save-dev electron
修改package.json
文件:
{
"name": "cdn-uploader",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron .", // 启动electron运行时
}
}
接下来,新建一个简单的main.js
:
const { app, BrowserWindow, ipcMain } = require('electron');
// 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 win
function createWindow() {
// 创建浏览器窗口。
win = new BrowserWindow({
width: 800,
height: 800
});
// 并且为你的应用加载index.html
win.loadFile('index.html');
// 当 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();
}
})
// 在这个文件中,你可以续写应用剩下主进程代码。这里的主进程,就是Node进程.
接下来,我们只需要新建一个简单index.html
就可以了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>cdn-uploader</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
在命令行执行npm start
,即可启动一个Electron应用了。
开发前端页面
Electron的GUI界面,其实就是一个网页。我们可以按照正常开发网页的方式,来开发界面。只需要将main.js
中的地址改为你本地启的前端页面地址即可,如:
win.loadURL('http://localhost:8003');
和传统的前端页面开发不同的是,我们的网页不是运行在浏览器内,而是运行在Electron中。
这里,我选择了react和ant-design来开发前端页面。
前后端通信
Electron后端是使用Node.js作为运行时的。我们可以直接通过Electron的Node.js运行时,提供后台服务。
在本文所介绍的示例中,由于没有http的文件直传接口,因此我是在Node端完成的文件上传服务。
// 前端向后台Node进程发送消息:
const { ipcRenderer } = require('electron');
ipcRenderer.send('uploadFile', {
payload: {...}
});
// 前端监听后台Node进程发过来的消息:
ipcRenderer.on('uploadFileSuccess', (event, arg) => {
const { msg,code } = arg;
console.log('上传成功', msg);
...
});
// 后台Node进程(main.js)接收前端的消息:
const { ipcMain } = require('electron');
ipcMain.on('uploadFile', (event, arg) => {
const { payload } = arg;
...
// 后台Node进程通知前端上传成功
event.sender.send('uploadFileSuccess', {
msg: 'ok',
code: 0
});
});
项目打包
当开发完成,需要打包时,首先,我们按照正常网页开发一样,完成前端代码的打包。然后,修改主进程main.js的代码:
win.loadURL(url.format({
pathname: path.join(__dirname, './dist/h5/index.html'), // 前端代码打包产出的html地址
protocol: 'file:',
slashes: true
}));
当然,我们可以直接增加环境变量,避免开发和打包时,反复修改代码。
// main.js
if (process.env.NODE_ENV === 'dev') {
win.loadURL('http://localhost:8003');
win.webContents.openDevTools();
} else {
win.loadURL(url.format({
pathname: path.join(__dirname, './dist/h5/index.html'),
protocol: 'file:',
slashes: true
}));
}
// package.json
{
"name": "cdn-uploader",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "cross-env NODE_ENV=dev electron ." // 加上环境变量
}
}
有一点需要注意的是,在前端页面打包配置中(以webpack为例),需要指定
target: 'electron-renderer'
最后,使用命令行工具electron-packager,就可以产出桌面应用了。
// package.json
{
"name": "cdn-uploader",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "cross-env NODE_ENV=dev electron .", // 加上环境变量
"make": "electron-packager ./ cdn-uploader --out ./outApp --overwrite --progress" // 产出桌面应用
}
}
更多细节
想要了解更多,可以直接参考Electron的官方文档:
写在后面
本文简单介绍了开发一个Electron应用的流程。偶尔开发一些Electron小工具,提高工作生产效率,是一个不错的选择,符合预期。
共同学习,写下你的评论
评论加载中...
作者其他优质文章