437 lines
11 KiB
Markdown
437 lines
11 KiB
Markdown
|
|
# 应用打包方案对比与实现
|
|||
|
|
|
|||
|
|
本文档详细说明 ElectronEgg 应用的两种打包方案:纯绿色版方案 和 双版本方案。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 方案对比
|
|||
|
|
|
|||
|
|
| 特性 | 方案一:纯绿色版 | 方案二:双版本打包 |
|
|||
|
|
|------|-----------------|-------------------|
|
|||
|
|
| **打包产物** | 单个便携版 exe | 安装版 exe + 便携版 exe |
|
|||
|
|
| **安装过程** | 无需安装 | 安装版需安装,便携版无需 |
|
|||
|
|
| **桌面快捷方式** | 应用内自动创建 | 安装版自动创建,便携版手动或自动 |
|
|||
|
|
| **开始菜单** | 无 | 安装版有 |
|
|||
|
|
| **卸载程序** | 无(直接删除) | 安装版有 |
|
|||
|
|
| **适用场景** | 临时使用、U盘携带 | 正式部署、企业分发 |
|
|||
|
|
| **用户体验** | 灵活、轻量 | 专业、完整 |
|
|||
|
|
| **打包时间** | 快 | 较慢(打包两次) |
|
|||
|
|
| **分发复杂度** | 简单(单文件) | 中等(两个文件) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 方案一:纯绿色版 + 自动创建快捷方式
|
|||
|
|
|
|||
|
|
### 特点
|
|||
|
|
- ✅ 单个 exe 文件,双击即用
|
|||
|
|
- ✅ 首次启动时询问是否创建桌面快捷方式
|
|||
|
|
- ✅ 无需安装,无需卸载
|
|||
|
|
- ✅ 适合快速分发和临时使用
|
|||
|
|
|
|||
|
|
### 实现步骤
|
|||
|
|
|
|||
|
|
#### 1. 修改打包配置
|
|||
|
|
|
|||
|
|
**文件**:[cmd/builder.json](../cmd/builder.json)
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"productName": "南京灿能工具",
|
|||
|
|
"appId": "com.canneng.tool",
|
|||
|
|
"copyright": "© 2025 hongawen",
|
|||
|
|
"directories": {
|
|||
|
|
"output": "out"
|
|||
|
|
},
|
|||
|
|
"asar": true,
|
|||
|
|
"files": [
|
|||
|
|
"**/*",
|
|||
|
|
"!cmd/",
|
|||
|
|
"!data/",
|
|||
|
|
"!electron/",
|
|||
|
|
"!frontend/",
|
|||
|
|
"!logs/",
|
|||
|
|
"!out/",
|
|||
|
|
"!go/",
|
|||
|
|
"!python/"
|
|||
|
|
],
|
|||
|
|
"extraResources": {
|
|||
|
|
"from": "build/extraResources/",
|
|||
|
|
"to": "extraResources"
|
|||
|
|
},
|
|||
|
|
"publish": [
|
|||
|
|
{
|
|||
|
|
"provider": "generic",
|
|||
|
|
"url": "https://your-update-server.com"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"win": {
|
|||
|
|
"icon": "build/icons/icon.ico",
|
|||
|
|
"artifactName": "${productName}-${os}-${version}-${arch}.${ext}",
|
|||
|
|
"target": [
|
|||
|
|
{
|
|||
|
|
"target": "portable"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 添加自动创建快捷方式功能
|
|||
|
|
|
|||
|
|
**文件**:[electron/preload/lifecycle.js](../electron/preload/lifecycle.js)
|
|||
|
|
|
|||
|
|
在 `windowReady()` 钩子中添加以下代码:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const { logger } = require('ee-core/log');
|
|||
|
|
const { getConfig } = require('ee-core/config');
|
|||
|
|
const { getMainWindow } = require('ee-core/electron');
|
|||
|
|
|
|||
|
|
class Lifecycle {
|
|||
|
|
|
|||
|
|
async ready() {
|
|||
|
|
logger.info('[lifecycle] ready');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async electronAppReady() {
|
|||
|
|
logger.info('[lifecycle] electron-app-ready');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async windowReady() {
|
|||
|
|
logger.info('[lifecycle] window-ready');
|
|||
|
|
|
|||
|
|
// 延迟加载,无白屏
|
|||
|
|
const { windowsOption } = getConfig();
|
|||
|
|
if (windowsOption.show == false) {
|
|||
|
|
const win = getMainWindow();
|
|||
|
|
win.once('ready-to-show', () => {
|
|||
|
|
win.show();
|
|||
|
|
win.focus();
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 绿色版自动创建桌面快捷方式
|
|||
|
|
await this.createDesktopShortcut();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 为绿色版创建桌面快捷方式
|
|||
|
|
*/
|
|||
|
|
async createDesktopShortcut() {
|
|||
|
|
const { app, dialog, shell } = require('electron');
|
|||
|
|
const path = require('path');
|
|||
|
|
const fs = require('fs');
|
|||
|
|
|
|||
|
|
// 判断是否为便携版(绿色版)
|
|||
|
|
// 安装版通常在 C:\Program Files 或 AppData\Local\Programs
|
|||
|
|
const isPortable = process.platform === 'win32' &&
|
|||
|
|
!process.execPath.includes('Program Files') &&
|
|||
|
|
!process.execPath.includes('AppData\\Local\\Programs');
|
|||
|
|
|
|||
|
|
if (!isPortable) {
|
|||
|
|
logger.info('[lifecycle] 非便携版,跳过快捷方式创建');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const desktopPath = app.getPath('desktop');
|
|||
|
|
const shortcutPath = path.join(desktopPath, '南京灿能工具.lnk');
|
|||
|
|
|
|||
|
|
// 如果快捷方式已存在,跳过
|
|||
|
|
if (fs.existsSync(shortcutPath)) {
|
|||
|
|
logger.info('[lifecycle] 桌面快捷方式已存在');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 询问用户是否创建快捷方式
|
|||
|
|
const result = await dialog.showMessageBox({
|
|||
|
|
type: 'question',
|
|||
|
|
buttons: ['创建', '跳过'],
|
|||
|
|
defaultId: 0,
|
|||
|
|
title: '创建桌面快捷方式',
|
|||
|
|
message: '是否在桌面创建快捷方式?',
|
|||
|
|
detail: '方便您下次快速启动应用'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (result.response === 0) {
|
|||
|
|
// Windows 下创建快捷方式
|
|||
|
|
const success = shell.writeShortcutLink(shortcutPath, {
|
|||
|
|
target: process.execPath,
|
|||
|
|
cwd: path.dirname(process.execPath),
|
|||
|
|
description: '南京灿能C端工具',
|
|||
|
|
icon: process.execPath,
|
|||
|
|
iconIndex: 0
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (success) {
|
|||
|
|
logger.info('[lifecycle] 桌面快捷方式创建成功');
|
|||
|
|
await dialog.showMessageBox({
|
|||
|
|
type: 'info',
|
|||
|
|
title: '成功',
|
|||
|
|
message: '桌面快捷方式已创建',
|
|||
|
|
buttons: ['确定']
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
logger.error('[lifecycle] 桌面快捷方式创建失败');
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
logger.info('[lifecycle] 用户跳过创建快捷方式');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
logger.error('[lifecycle] 创建快捷方式时出错:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async beforeClose() {
|
|||
|
|
logger.info('[lifecycle] before-close');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Lifecycle.toString = () => '[class Lifecycle]';
|
|||
|
|
|
|||
|
|
module.exports = {
|
|||
|
|
Lifecycle
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. 打包命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
npm run build # 完整构建
|
|||
|
|
npm run build-w # 打包 Windows 便携版
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. 产物说明
|
|||
|
|
|
|||
|
|
打包完成后,在 `out/` 目录下会生成:
|
|||
|
|
```
|
|||
|
|
out/
|
|||
|
|
└── 南京灿能工具-win-4.0.0-x64.exe (便携版,约 150-200MB)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 方案二:双版本打包(安装版 + 便携版)
|
|||
|
|
|
|||
|
|
### 特点
|
|||
|
|
- ✅ 提供两种版本供用户选择
|
|||
|
|
- ✅ 安装版:专业、完整的安装体验
|
|||
|
|
- ✅ 便携版:灵活、轻量,无需安装
|
|||
|
|
- ✅ 适合正式产品发布
|
|||
|
|
|
|||
|
|
### 实现步骤
|
|||
|
|
|
|||
|
|
#### 1. 修改打包配置
|
|||
|
|
|
|||
|
|
**文件**:[cmd/builder.json](../cmd/builder.json)
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"productName": "南京灿能工具",
|
|||
|
|
"appId": "com.canneng.tool",
|
|||
|
|
"copyright": "© 2025 hongawen",
|
|||
|
|
"directories": {
|
|||
|
|
"output": "out"
|
|||
|
|
},
|
|||
|
|
"asar": true,
|
|||
|
|
"files": [
|
|||
|
|
"**/*",
|
|||
|
|
"!cmd/",
|
|||
|
|
"!data/",
|
|||
|
|
"!electron/",
|
|||
|
|
"!frontend/",
|
|||
|
|
"!logs/",
|
|||
|
|
"!out/",
|
|||
|
|
"!go/",
|
|||
|
|
"!python/"
|
|||
|
|
],
|
|||
|
|
"extraResources": {
|
|||
|
|
"from": "build/extraResources/",
|
|||
|
|
"to": "extraResources"
|
|||
|
|
},
|
|||
|
|
"nsis": {
|
|||
|
|
"oneClick": false,
|
|||
|
|
"allowElevation": true,
|
|||
|
|
"allowToChangeInstallationDirectory": true,
|
|||
|
|
"installerIcon": "build/icons/icon.ico",
|
|||
|
|
"uninstallerIcon": "build/icons/icon.ico",
|
|||
|
|
"installerHeaderIcon": "build/icons/icon.ico",
|
|||
|
|
"createDesktopShortcut": true,
|
|||
|
|
"createStartMenuShortcut": true,
|
|||
|
|
"shortcutName": "南京灿能工具",
|
|||
|
|
"artifactName": "${productName}-Setup-${version}.${ext}"
|
|||
|
|
},
|
|||
|
|
"portable": {
|
|||
|
|
"artifactName": "${productName}-Portable-${version}.${ext}"
|
|||
|
|
},
|
|||
|
|
"publish": [
|
|||
|
|
{
|
|||
|
|
"provider": "generic",
|
|||
|
|
"url": "https://your-update-server.com"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"win": {
|
|||
|
|
"icon": "build/icons/icon.ico",
|
|||
|
|
"target": [
|
|||
|
|
{
|
|||
|
|
"target": "nsis",
|
|||
|
|
"arch": ["x64"]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"target": "portable",
|
|||
|
|
"arch": ["x64"]
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 便携版快捷方式功能(可选)
|
|||
|
|
|
|||
|
|
如果希望便携版也能自动创建快捷方式,使用**方案一**中的 `createDesktopShortcut()` 代码。
|
|||
|
|
|
|||
|
|
#### 3. 打包命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
npm run build # 完整构建
|
|||
|
|
npm run build-w # 打包两个版本
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. 产物说明
|
|||
|
|
|
|||
|
|
打包完成后,在 `out/` 目录下会生成:
|
|||
|
|
```
|
|||
|
|
out/
|
|||
|
|
├── 南京灿能工具-Setup-4.0.0.exe (安装版,约 150MB)
|
|||
|
|
└── 南京灿能工具-Portable-4.0.0.exe (便携版,约 150-200MB)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 5. 版本差异说明
|
|||
|
|
|
|||
|
|
**安装版 (NSIS)**:
|
|||
|
|
- 需要安装到系统(默认 C:\Program Files)
|
|||
|
|
- 自动创建桌面快捷方式
|
|||
|
|
- 自动创建开始菜单项
|
|||
|
|
- 提供卸载程序
|
|||
|
|
- 支持自动更新
|
|||
|
|
- 适合企业部署、长期使用
|
|||
|
|
|
|||
|
|
**便携版 (Portable)**:
|
|||
|
|
- 单个 exe 文件
|
|||
|
|
- 双击直接运行(首次会自解压)
|
|||
|
|
- 无需安装,无需卸载
|
|||
|
|
- 可放在 U 盘随身携带
|
|||
|
|
- 适合临时使用、测试环境
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 快捷方式创建原理(技术细节)
|
|||
|
|
|
|||
|
|
### Windows 快捷方式 (.lnk)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
shell.writeShortcutLink(shortcutPath, {
|
|||
|
|
target: process.execPath, // 目标程序路径
|
|||
|
|
cwd: path.dirname(process.execPath), // 工作目录
|
|||
|
|
description: '应用描述', // 快捷方式描述
|
|||
|
|
icon: process.execPath, // 图标路径
|
|||
|
|
iconIndex: 0, // 图标索引
|
|||
|
|
args: '', // 启动参数(可选)
|
|||
|
|
appUserModelId: 'com.app.id' // Windows 应用 ID(可选)
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 判断是否为便携版
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const isPortable = process.platform === 'win32' &&
|
|||
|
|
!process.execPath.includes('Program Files') &&
|
|||
|
|
!process.execPath.includes('AppData\\Local\\Programs');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**原理**:
|
|||
|
|
- 安装版通常安装在 `C:\Program Files\YourApp\`
|
|||
|
|
- 或者 `C:\Users\用户名\AppData\Local\Programs\YourApp\`
|
|||
|
|
- 便携版可以在任意位置运行
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 推荐配置
|
|||
|
|
|
|||
|
|
### 企业级应用(推荐方案二)
|
|||
|
|
```
|
|||
|
|
✅ 提供两个版本
|
|||
|
|
✅ 主推安装版(专业形象)
|
|||
|
|
✅ 提供便携版作为备选
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 轻量工具(推荐方案一)
|
|||
|
|
```
|
|||
|
|
✅ 只提供便携版
|
|||
|
|
✅ 应用内自动创建快捷方式
|
|||
|
|
✅ 简化分发流程
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### Q1: 便携版首次启动为什么慢?
|
|||
|
|
**A**: 便携版是自解压程序,首次运行需要解压资源到临时目录(约 3-5 秒)。后续启动会快很多。
|
|||
|
|
|
|||
|
|
### Q2: 便携版数据存储在哪里?
|
|||
|
|
**A**:
|
|||
|
|
- 用户数据:`C:\Users\用户名\AppData\Roaming\你的appId\`
|
|||
|
|
- 临时文件:`C:\Users\用户名\AppData\Local\Temp\`
|
|||
|
|
|
|||
|
|
### Q3: 如何让便携版也支持自动更新?
|
|||
|
|
**A**: 需要配置 `electron-updater`,但便携版更新体验不如安装版。建议:
|
|||
|
|
- 安装版:使用自动更新
|
|||
|
|
- 便携版:提示用户下载新版本
|
|||
|
|
|
|||
|
|
### Q4: 可以同时运行两个版本吗?
|
|||
|
|
**A**: 不建议。虽然技术上可行,但会导致数据冲突(共享同一个 userData 目录)。
|
|||
|
|
|
|||
|
|
### Q5: 如何自定义快捷方式图标?
|
|||
|
|
**A**: 在 `build/icons/` 目录放置 `.ico` 文件,并在 `builder.json` 中配置:
|
|||
|
|
```json
|
|||
|
|
"win": {
|
|||
|
|
"icon": "build/icons/custom-icon.ico"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 测试检查清单
|
|||
|
|
|
|||
|
|
打包完成后,请进行以下测试:
|
|||
|
|
|
|||
|
|
### 安装版测试
|
|||
|
|
- [ ] 安装到默认路径成功
|
|||
|
|
- [ ] 安装到自定义路径成功
|
|||
|
|
- [ ] 桌面快捷方式正常
|
|||
|
|
- [ ] 开始菜单项正常
|
|||
|
|
- [ ] 应用启动正常
|
|||
|
|
- [ ] 卸载程序正常
|
|||
|
|
|
|||
|
|
### 便携版测试
|
|||
|
|
- [ ] 双击 exe 正常启动
|
|||
|
|
- [ ] 首次启动自动创建快捷方式(如已实现)
|
|||
|
|
- [ ] 桌面快捷方式可用
|
|||
|
|
- [ ] 应用功能正常
|
|||
|
|
- [ ] 关闭后再次启动正常
|
|||
|
|
- [ ] 可移动到其他目录运行
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 参考资源
|
|||
|
|
|
|||
|
|
- electron-builder 官方文档: https://www.electron.build/
|
|||
|
|
- NSIS 配置: https://www.electron.build/configuration/nsis
|
|||
|
|
- Portable 配置: https://www.electron.build/configuration/portable
|
|||
|
|
- Electron shell API: https://www.electronjs.org/docs/latest/api/shell
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*文档创建时间: 2025-10-14*
|
|||
|
|
*作者: hongawen*
|