将前后端分离版的前端vue打包成EXE的完整解决方案
将若依前后端分离版的前端打包成EXE的完整解决方案
将若依前后端分离版的Vue前端打包成Windows可执行文件(.exe),同时保持与后端API的通信,需要使用Electron框架来实现。下面是详细的步骤和解决方案。
一、准备工作
1. 环境要求
- Node.js (推荐v16+)
- npm 或 yarn
- 若依前后端分离版的前端代码
- Git
2. 相关技术栈
- Vue.js (若依前端使用)
- Electron (桌面应用打包框架)
- electron-builder (打包工具)
二、项目改造步骤
1. 安装Electron相关依赖
首先,进入若依前端项目目录,安装Electron相关依赖:
# 进入若依前端项目目录
cd ruoyi-ui# 安装Electron相关依赖
npm install electron electron-builder --save-dev# 安装其他必要的依赖
npm install electron-is-dev electron-store --save
2. 创建Electron主进程文件
在项目根目录创建Electron主进程文件:
const { app, BrowserWindow, Menu, shell, dialog } = require('electron');
const path = require('path');
const isDev = require('electron-is-dev');
const Store = require('electron-store');// 初始化配置存储
Store.initRenderer();
const store = new Store();// 保存主窗口对象的引用
let mainWindow;// 创建主窗口
function createWindow() {// 创建浏览器窗口mainWindow = new BrowserWindow({width: 1280,height: 800,minWidth: 1024,minHeight: 768,icon: path.join(__dirname, '../public/favicon.ico'),webPreferences: {nodeIntegration: true,contextIsolation: false,webSecurity: false, // 允许跨域请求preload: path.join(__dirname, 'preload.js')}});// 加载应用if (isDev) {// 开发环境下加载开发服务器地址mainWindow.loadURL('http://localhost:80');// 打开开发者工具mainWindow.webContents.openDevTools();} else {// 生产环境下加载打包后的index.htmlmainWindow.loadFile(path.join(__dirname, '../dist/index.html'));}// 当窗口关闭时触发mainWindow.on('closed', () => {mainWindow = null;});// 创建菜单createMenu();
}// 创建应用菜单
function createMenu() {const template = [{label: '文件',submenu: [{label: '设置API地址',click: () => {configApiUrl();}},{ type: 'separator' },{label: '退出',accelerator: 'CmdOrCtrl+Q',click: () => {app.quit();}}]},{label: '编辑',submenu: [{ role: 'undo', label: '撤销' },{ role: 'redo', label: '重做' },{ type: 'separator' },{ role: 'cut', label: '剪切' },{ role: 'copy', label: '复制' },{ role: 'paste', label: '粘贴' }]},{label: '视图',submenu: [{ role: 'reload', label: '刷新' },{ role: 'forceReload', label: '强制刷新' },{ role: 'toggleDevTools', label: '开发者工具' },{ type: 'separator' },{ role: 'resetZoom', label: '实际大小' },{ role: 'zoomIn', label: '放大' },{ role: 'zoomOut', label: '缩小' },{ type: 'separator' },{ role: 'togglefullscreen', label: '全屏' }]},{label: '帮助',submenu: [{label: '关于',click: () => {dialog.showMessageBox({title: '关于',message: '若依管理系统桌面版',detail: `版本: ${app.getVersion()}\n若依是一款优秀的开源后台管理系统。`});}},{label: '访问官网',click: () => {shell.openExternal('http://ruoyi.vip');}}]}];const menu = Menu.buildFromTemplate(template);Menu.setApplicationMenu(menu);
}// 配置API地址
function configApiUrl() {// 获取当前API地址const currentApiUrl = store.get('apiUrl') || 'http://localhost:8080';// 显示输入对话框dialog.showInputBox({title: '设置API地址',label: '请输入后端API地址:',value: currentApiUrl,inputAttrs: {type: 'url'},buttons: ['确定', '取消'],defaultId: 0,cancelId: 1}).then(result => {if (!result.canceled && result.text) {// 保存新的API地址store.set('apiUrl', result.text);// 提示用户重启应用dialog.showMessageBox({type: 'info',title: '设置成功',message: 'API地址已更新,请重启应用以应用更改。',buttons: ['重启', '稍后']}).then(res => {if (res.response === 0) {app.relaunch();app.exit(0);}});}}).catch(err => {console.error('设置API地址出错:', err);});
}// 当Electron完成初始化并准备创建浏览器窗口时调用此方法
app.whenReady().then(() => {createWindow();app.on('activate', () => {// 在macOS上,当点击dock图标并且没有其他窗口打开时,// 通常在应用程序中重新创建一个窗口。if (BrowserWindow.getAllWindows().length === 0) {createWindow();}});
});// 当所有窗口关闭时退出应用
app.on('wind