最近想要制作一个 Windows 工具箱,所以需要多集合一些功能。之前用 uniapp 制作了一些功能,为了省事,所以想要把部分 uniapp 封装成 exe 来丰富功能。
看了一下,由于 uniapp 并未提供打包 exe 的方法,所以需要借助 electron 来对编译后的内容进行打包。
最近萌生了制作一个 Windows 工具箱 的想法,希望它能整合多种实用功能,方便日常使用。由于之前用 UniApp 制作了一些工具,为了节省开发时间和重复工作量,我决定将部分 UniApp 项目封装为 EXE 文件,以丰富工具箱的功能。
UniApp 打包 EXE 的限制
UniApp 是一个强大的跨平台开发框架,支持多平台(如 H5、小程序、App)的快速开发,但目前官方并未提供直接打包成 Windows EXE 的方法。因此,我们需要借助其他工具实现这一目标。在调研过程中发现,Electron 是一个很适合的选择。
为什么选择 Electron?
Electron 是一个用于构建跨平台桌面应用的框架,基于 Chromium 和 Node.js,允许使用 Web 技术(如 HTML、CSS 和 JavaScript)构建桌面应用。以下是它的一些优势:
- 易用性:Electron 的生态成熟,能够轻松加载 HTML 文件或 Web 项目。
- 兼容性强:支持 Windows、macOS 和 Linux,开发一次即可多平台运行。
- 与 UniApp 结合性:可以将 UniApp 项目的 H5 版本嵌入 Electron,轻松实现功能扩展。
项目实现步骤
接下来简单讲一下使用 Electron 将 UniApp 封装为 EXE 的具体流程:
1. 准备 UniApp 项目
首先,需要将 UniApp 项目构建为 H5 版本。步骤如下:
- 打开 HBuilderX,加载你的 UniApp 项目。
- 点击菜单栏 发行 -> 网站(H5)。
- 等待构建完成后,在项目目录中会生成一个
dist
文件夹,其中包含 H5 的静态文件。
2. 创建 Electron 项目
安装 Node.js 环境后(默认大家都安装了),按照以下步骤创建一个 Electron 项目:
1、初始化项目:
准备一个正常可以打包成 web 的正常 uniapp 项目
2、安装 Electron:
npm install electron --save-dev
安装出错了,报了以下错误,看起来像是连接超时了,换了几次源发现都不行,查资料发现安装 Electron 时需要安装 Github 内容,下载不全才导致的。
C:UsersAdministrator.DESKTOP-8NNEK6T>npm install -g electron
npm warn deprecated boolean@3.2.0: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
npm warn cleanup Failed to remove some directories [
npm warn cleanup [
npm warn cleanup 'C:\Users\Administrator.DESKTOP-8NNEK6T\AppData\Roaming\npm\node_modules\electron',
npm warn cleanup [Error: EPERM: operation not permitted, rmdir 'C:UsersAdministrator.DESKTOP-8NNEK6TAppDataRoamingnpmnode_moduleselectronnode_modulesdecompress-response'] {
npm warn cleanup errno: -4048,
npm warn cleanup code: 'EPERM',
npm warn cleanup syscall: 'rmdir',
npm warn cleanup path: 'C:\Users\Administrator.DESKTOP-8NNEK6T\AppData\Roaming\npm\node_modules\electron\node_modules\decompress-response'
npm warn cleanup }
npm warn cleanup ],
npm warn cleanup [
npm warn cleanup '\\?\C:\Users\Administrator.DESKTOP-8NNEK6T\AppData\Roaming\npm\node_modules\electron\node_modules',
npm warn cleanup [Error: EPERM: operation not permitted, rmdir 'C:UsersAdministrator.DESKTOP-8NNEK6TAppDataRoamingnpmnode_moduleselectronnode_modulesglobal-agent'] {
npm warn cleanup errno: -4048,
npm warn cleanup code: 'EPERM',
npm warn cleanup syscall: 'rmdir',
npm warn cleanup path: 'C:\Users\Administrator.DESKTOP-8NNEK6T\AppData\Roaming\npm\node_modules\electron\node_modules\global-agent'
npm warn cleanup }
npm warn cleanup ]
npm warn cleanup ]
npm error code 1
npm error path C:UsersAdministrator.DESKTOP-8NNEK6TAppDataRoamingnpmnode_moduleselectron
npm error command failed
npm error command C:WINDOWSsystem32cmd.exe /d /s /c node install.js
npm error RequestError: connect ETIMEDOUT 20.205.243.166:443
npm error at ClientRequest.<anonymous> (C:UsersAdministrator.DESKTOP-8NNEK6TAppDataRoamingnpmnode_moduleselectronnode_modulesgotdistsourcecoreindex.js:970:111)
npm error at Object.onceWrapper (node:events:633:26)
npm error at ClientRequest.emit (node:events:530:35)
npm error at origin.emit (C:UsersAdministrator.DESKTOP-8NNEK6TAppDataRoamingnpmnode_moduleselectronnode_modules@szmarczakhttp-timerdistsourceindex.js:43:20)
npm error at emitErrorEvent (node:_http_client:103:11)
npm error at TLSSocket.socketErrorListener (node:_http_client:506:5)
npm error at TLSSocket.emit (node:events:518:28)
npm error at emitErrorNT (node:internal/streams/destroy:170:8)
npm error at emitErrorCloseNT (node:internal/streams/destroy:129:3)
npm error at process.processTicksAndRejections (node:internal/process/task_queues:90:21)
npm error at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1610:16)
npm error A complete log of this run can be found in: C:UsersAdministrator.DESKTOP-8NNEK6TAppDataLocalnpm-cache_logs2024-12-31T08_52_55_131Z-debug-0.log
第一种方法就是设置代理,第二种方法就是单独设置 ELECTRON_MIRROR
环境变量:
步骤(无问题跳过):
1. 设置临时环境变量
在 PowerShell 中设置环境变量 ELECTRON_MIRROR
,指向国内镜像地址。打开 PowerShell 窗口并执行以下命令:
$env:ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
这个会在 PowerShell 会话中临时设置 ELECTRON_MIRROR
环境变量。
2. 安装 Electron
然后你可以执行以下命令来安装 Electron:
npm install --save-dev electron
这样 Electron 安装就能走国内的镜像源,而不是默认的 GitHub 源,从而减少因网络问题导致的安装失败。
3、大致结构:
打包后的内容在 unpackage/dist/build/web/
下,初始结构包括 index.html
,assets 目录以及 static 目录,需要创建你 main.js
以及 package.json
并补全相关内容即可。
4、编写 main.js
文件:
const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
app.on('ready', () => {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
},
});
// 加载 UniApp 打包后的文件
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// 开启开发者工具(可选)
// mainWindow.webContents.openDevTools();
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
5、编写 package.json
在 web 目录下新建 package.json
(npm)文件
{
"name": "进制计算器",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"devDependencies": {
"electron": "^23.1.0"
},
"author": "繁依Fanyi",
"license": "ISC"
}
3. 打包为 EXE
完成 Electron 项目后,我们需要将其打包为 EXE 文件:
1、安装打包工具 electron-packager:
npm install electron-packager --save-dev
2、执行打包命令:
npx electron-packager . my-toolbox --platform=win32 --arch=x64 --out=release-build --overwrite
my-toolbox 是打包后的二进制 exe 名称,而不是应用上方显示的名称
想要修改这个名称,可以在WEB发行时修改网站标题即可
打包的时候可能会出现找不到包的情况 can't found module xxx .... from 某某路径
,这时候可以把找不到的包写在 package.json
中的 devDependences 下配置,我这里是找不到 electron,所以就直接配置了 electron,然后 npm install
安装依赖即可。
打包过程中也可能会出现 connect ETIMEDOUT 20.205.243.166:443
的问题,所以我还是建议直接把 $env:ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
配置到环境变量中。
3、打包成功后,release-build
文件夹中会生成 my-toolbox.exe
文件,双击即可运行。
如果打包后内容空白,可能是打包时没有配置 manifest.json
中的基础路径,我是自己写的小应用,https也取消了
设置基础路径为 ./
,保存后重新打包 h5 就行了。
打包成功后就是这样了
打包exe后的内容如下,点击 exe 即可运行。
4. 优化和注意事项
- 静态资源加载问题:确保文件夹完整无误地放在项目根目录。
- 打包大小优化:Electron 打包的文件可能较大,可以使用压缩工具(如
electron-builder
)进一步优化。 - 功能扩展:可以在 Electron 中添加更多桌面功能(如系统托盘、文件操作等),以增强工具箱的实用性。
- 样式优化:编写相关参数优化窗口大小,样式等来进一步美化。
1、窗口优化
首先时窗口大小,宽屏不太适合这个比较长的计算器,所以需要限制窗口大小为 600 * 1000 左右范围,设置范围内等比缩放,隐藏顶部菜单栏:
const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
app.on('ready', () => {
mainWindow = new BrowserWindow({
width: 300, // 初始宽度
height: 600, // 初始高度
minWidth: 300, // 最小宽度
minHeight: 600, // 最小高度
maxWidth: 1200, // 最大宽度
maxHeight: 2000, // 最大高度
webPreferences: {
nodeIntegration: true,
},
autoHideMenuBar: true, // 隐藏菜单栏
// 如果不想让鼠标点击窗口顶部区域时自动显示菜单栏,可以加上下面的代码
// hideMenuBar: true,
});
// 加载 UniApp 打包后的文件
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// 设置初始宽高比为 0.5
mainWindow.setAspectRatio(0.5);
// 开启开发者工具(可选)
// mainWindow.webContents.openDevTools();
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
2、滚动条优化
如果希望完全隐藏滚动条,可以在 index.html
的