背景
公司需要制作一个桌面程序,之前有一个python
写的cli
工具,需要封装一个GUI
跨平台使用,技术采用Electron
+ Vue
技术栈,模板使用electron-vue,特殊之处是应用中使用pyinstaller
打包成跨平台应用使用node
调用。
基础项目中遇到的问题
上面提到该项目是根据electron-vue
模板创建,在创建时,选用了electron-builder
作为打包工具,打包后会在build
目录下生成*-unpacked
目录和对应的.exe
、.deb
等可安装文件。下面说下基于该模板开发时遇到的问题。
升级electron
版本
- 模板使用的
electron
版本是2.X
版本,版本较低,故升级到了11.3.0
版本,以方便使用最新的框架特性 - 升级后模板自带的
vuex-electron
插件不好使故去掉了
系统中的路径分隔符的问题
- 由于历史原因路劲的分割符在
Windows
和POSIX
不同\
反斜杠,在Windows
,如C:\tmp\test.txt
/
斜杆,在POSIX
,如/tmp/test.txt
- 各个编程语言均有获取当前系统分隔符方法的api,
node
中可以使用:const sep = require('path').sep
- 故在手动添加路径的地方需要通过上面提到的
api
获取路径分割符,动态进行拼接:import path from 'path' const downloadPath = `${this.$electron.remote.app.getPath('downloads')}${path.sep}合并表格.xlsx`
关于使用electron-builder
打包遇到的问题
- 据说使用
electron-builder
可以打包出跨操作系统的应用程序,保险起见,在Windows
和Deepin
系统分别进行打包 - 打包的配置基本通过
package.json
即可配置完成:"build": { "productName": "excel-util", "appId": "com.excelUtil.xxx", "directories": { "output": "build" }, "files": [ "dist/electron/**/*" ], "dmg": { "contents": [ { "x": 410, "y": 150, "type": "link", "path": "/Applications" }, { "x": 130, "y": 150, "type": "file" } ] }, "mac": { "icon": "build/icons/icon.icns" }, "win": { "icon": "build/icons/icon.ico" }, "nsis": { "shortcutName": "ExcelUtil", "oneClick": false, "allowToChangeInstallationDirectory": true, "include": "./installer.nsh" }, "asar": false, "linux": { "icon": "build/icons", "target": "deb" } }
- 以上是
electron-builder
中关于打包的所有配置,下面拆分一下Windows
打包配置,指定图标路径和nsis
配置Windows
应用安装和卸载的行为"win": { "icon": "build/icons/icon.ico" }, "nsis": { "shortcutName": "ExcelUtil", "oneClick": false, "allowToChangeInstallationDirectory": true, "include": "./installer.nsh" }
Linux
打包配置,指定图标和打包目标格式等"linux": { "icon": "build/icons", "target": "deb" }
- 打包使用的依赖包的镜像问题
- 打包会依赖很多外部的安装包,默认都是通过
github
或者npm
官方仓库,会有下载缓慢或者下载失败的问题 - 需要增加
.yarnrc
配置文件在根目录下,配置下载涉及到依赖的的仓库地址registry "https://registry.npm.taobao.org" sass_binary_site "https://npm.taobao.org/mirrors/node-sass/" phantomjs_cdnurl "http://cnpmjs.org/downloads" electron_mirror "https://npm.taobao.org/mirrors/electron/" sqlite3_binary_host_mirror "https://foxgis.oss-cn-shanghai.aliyuncs.com/" profiler_binary_host_mirror "https://npm.taobao.org/mirrors/node-inspector/" chromedriver_cdnurl "https://cdn.npm.taobao.org/dist/chromedriver"
- 打包会依赖很多外部的安装包,默认都是通过
开发中遇到的问题
主进程和渲染进程
electron
本质是一个nodejs runtime
和一个开源的chromium
浏览器,开发时分为主进程和渲染进程- 主进程的代码在
src/main
目录下 - 渲染进程的代码在
src/renderer
目录下 - 同时会通过
webpack
分别对main
和renderer
进行打包构建 - 进程间通信可以使用
ipcMain
和ipcRenderer
中的事件进行通信,以达到渲染进程可以调用主进程中的原生资源
主进程窗口配置
-
由于本次开发涉及的主进程开发相对简单,只涉及到一个
src/main/index.js
,那就直接拿文件中BrowserWindow
配置代码说事儿吧new BrowserWindow({ height: 563, useContentSize: true, width: 1000, fullscreen: false, // 是否允许全屏 fullscreenable: false, titleBarStyle: 'hidden', maximizable: false, webPreferences: { nodeIntegration: true, // 是否引入node api 这样渲染进程就可以i使用node api了 nodeIntegrationInWorker: true, enableRemoteModule: true // 是否引入remote模块 这样渲染进程就可以使用remote模块api了 } })
-
当然其中还涉及到引用本地数据库
lowdb
,这里是参考掘友的文章 -
本应用还涉及到了单窗口实现,使用的是
requestSingleInstanceLock api
来获取是否有窗口正在运行const gotTheLock = app.requestSingleInstanceLock() // 获取单体实例锁,设置应用单开 if (!gotTheLock) { app.quit() } else { app.on('second-instance', (event, commandLine, workingDirectory) => { // 当运行第二个实例时,将会聚焦到mainWindow这个窗口 if (mainWindow) { if (mainWindow.isMinimized()) mainWindow.restore() mainWindow.focus() } }) app.on('ready', createWindow) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (mainWindow === null) { createWindow() } }) }
调用python
应用程序时遇到的问题
- 首先需要通过
pyinstaller
分别打包出各操作系统环境中使用的cli
应用程序 - 将打包后的
cli
工具未压缩的包放入static/cli
目录下 - 调用时即可通过
webpack
吐出的全局__static
变量获取对应的路径供node
子进程调用 - 这里需要对打包配置进行修改才能达到打包后仍然可以正确调用
cli
-
package.json
的build
字段中增加"asar": false
,来保证打包后的应用不被压缩,node
仍可以正常访问cli
资源 -
对于
Windows
来说,通过配置nsis
的默认安装路径来保证路径可用,因为默认安装到C:\\Program Files
下,有空格的路径会造成调用不通,故需要增加一下配置"nsis": { "some": "other config", "include": "./installer.nsh" }
在
package.json
中增加一个nsis
安装脚本installer.nsh
,让应用默认安装到C:\excel-utils
目录下!macro preInit SetRegView 64 WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils" WriteRegExpandStr HkCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils" SetRegView 32 WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils" WriteRegExpandStr HkCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils" !macroend
-
对于
Deepin
系统来说,由于在webpack
打包复制static/cli
目录时会丢失cli
程序的可执行权限,导致打包后命令不能执行,故增加一个增加权限的脚本和命令
package.json
中"scripts": { "build:linux": "node .electron-vue/build.js && .electron-vue/changeMainMod.sh && electron-builder", }
.electron-vue
中增加changeMainMod.sh
,并使其在业务代码打包完成后调用#!/bin/bash for main in `ls ./dist/electron/static/cli/*/main` do echo "正在设置$main为可执行权限" chmod +x $main done
-
webpack.renderer.config
白名单的问题- 由于使用的
vue2.X
,UI
库使用的则是element-ui
,开发时发现使用el-table
组件不正确显示,查阅资料后发现需要增加到打包白名单里面,注释写的也很详细,需要指定UI libraries
来让编译.vue
文件
/** * List of node_modules to include in webpack bundle * * Required for specific packages like Vue UI libraries * that provide pure *.vue files that need compiling * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals */ let whiteListedModules = ['vue', 'element-ui']
- 由于使用的
番外
技术选型时有两个选择一个是Electron
,一个是NW.js
,这里有一个文档来说明二者的异同,主要区别就是:
Electron
有很多成功案例Atom
、VScode
等等耳熟能详的大众应用,当然NW.js
也有钉钉和微信开发者工具这样的巨头应用- 总体来说
Electron
有更多的用户群,更多三方工具包,更活跃的社区,有问题可以很快找到解决方案 NW.js
保持了对Windows xp
系统的支持,而Electron
并出于安全性考虑并不支持- 再就是对
node
的集成,Electron
集成了libuv
在两个进程中,均可以直接使用,避免了对Chromium
的hack,而NW.js
则需要通过派发的方式使用
搬砖
- electron
- electron-vue
- node
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!