electron打包exe程序,将后端jar包和前端vue都打包进去(前后端合体打包版)
前置准备(以后端java为例)
前端:vue/uniapp/react 打包好的dist文件
后端:java打包好的jar包
一、文件夹搭建
新建文件夹,然后在此文件夹打开cmd,npm init 初始化项目
文件夹路径如下图所示
my-electron-app // 项目目录名(可自定义)
———— resources //后端文件夹名
———————— yourBackend.jar // jar包
———— web // 前端文件夹名(存储着dist内部打包好的文件)
———————— assets、static、index.html等
———— main.js //重要!!! 这是打包所执行的js文件,需要自己创建!!
———— loading.html //可选 是打开程序之后的loading加载动画
———— package.json // 重要!!! 这是打包配置,自动生成,需要配置!!
———— dist //(打包后生成的文件夹,下文详细介绍)
二、安装electron 和 electron-builder
npm install electron --savedev
npm install electron-builder --savedev
三、安装其他所需依赖
npm install cross-env --save-dev//用于区分开发与生产环境
npm install iconv-lite --save-dev //转换编码轻量库 很适合java和node合体时使用
npm install tree-kill --save-dev //退出关闭程序时杀掉java进程
四、修改package.json 文件如示例
{
"name": "my-electron-app", // 项目名
"version": "1.0.0",
"main": "main.js", // js执行文件
"scripts": {// 项目名 start和build 区分开发和生产环境 需要安装 cross-env 否则运行或打包报错
"start": "cross-env NODE_ENV=development electron .",
"pack": "electron-packager . MyApp --platform=win32 --arch=x64 --out=dist --overwrite",
"build": "cross-env NODE_ENV=production electron-builder"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"cross-env": "^7.0.3",
"electron": "^35.0.0",
"electron-builder": "^25.1.8"
},
"dependencies": {
"iconv-lite": "^0.6.3",
"java-bridge": "^2.7.0",
"tree-kill": "^1.2.2"
},
"build":{//打包时一定要加入这个,否则打包之后的程序无法运行java后台
"extraResources":{
"from": "resources/yourBackend.jar",
"to": "yourBackend.jar"
}
},
"extraResources": [//打包时读取的web和resources
"web/**",
"resources/**"
]
}
五、新建main.js,进行如下配置
const { app, BrowserWindow } = require('electron');
const path = require('path');
const { exec } = require('child_process');
const treeKill = require('tree-kill');//杀java后台进程
let mainWindow;
let javaProcess;
// 如果未设置 NODE_ENV,默认视为开发环境
const isDev = process.env.NODE_ENV === 'development';
// 创建隐藏窗口
function createWindow() {
mainWindow = new BrowserWindow({
show: false, // 初始隐藏窗口
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
// 必须使用path.join(__dirname,否则打包时无法访问文件
mainWindow.loadFile(path.join(__dirname, 'loading.html')); // 加载等待页面
mainWindow.once('ready-to-show', () => {
mainWindow.show();
});
}
//启动java后台服务
function startJavaProcess() {
//console.log(process.env.NODE_ENV)
//console.log(process.resourcesPath)
const jarPath = isDev
? path.join(__dirname, './resources/yourBackend.jar')
: path.join(process.resourcesPath, 'yourBackendr.jar');
// 判断生产环境还是开发环境
// 启动 Java 进程并保存引用
javaProcess = exec(`java -jar "${jarPath}"`);
// 建议选择:处理 Java 输出
javaProcess.stdout.on('data', (data) => {
console.log('[Java output]', data.toString());
});
javaProcess.stderr.on('data', (data) => {
console.error('[Java Error]', data.toString());
});
// 进程意外退出时的处理(可选)
javaProcess.on('close', (code) => {
console.log(`Java quit 进程退出,代码: ${code}`);
});
}
// 终止进程
function killJavaProcess() {
if (javaProcess && javaProcess.pid) {
treeKill(javaProcess.pid, 'SIGTERM', (err) => {
if (err) console.error('endfailed终止失败:', err);
else console.log('Java ended进程已终止');
});
}
}
//软件刚开始时执行
app.whenReady().then(() => {
createWindow();
startJavaProcess();
// 延时 15 秒后加载页面(时间可自定义)
setTimeout(() => {
mainWindow.loadFile(path.join(__dirname, './web/index.html'));
}, 15000);
});
//软件关闭时执行
app.on('window-all-closed', () => {
console.log("window-all-closed");
if (javaProcess) {
killJavaProcess()// 关闭 Java 进程
}
if (process.platform !== 'darwin'){
// 2. 设置超时(5 秒后强制终止)
setTimeout(() => {
if (javaProcess) {
treeKill(javaProcess.pid, 'SIGKILL');
console.log('Java ended1111终止');
javaProcess = null;
app.quit();
}
}, 5000);
}
});
app.on('before-quit', () => {
if (javaProcess) {
javaProcess.kill('SIGTERM');// 关闭 Java 进程
javaProcess = null;
}
});
六、npm start 进行调试 试运行
七、调试没问题就npm run build 等待生成包
八、注意:
如果提示:ReferenceError: require is not defined in ES module scope, you can use import instead,解决方案见:ReferenceError: require is not defined in ES module scope, you can use import instead