233 lines
6.6 KiB
JavaScript
233 lines
6.6 KiB
JavaScript
/**
|
||
* Windows x64 自动打包脚本
|
||
* 功能:
|
||
* 1. 自动下载 Electron 并缓存到用户目录
|
||
* 2. 编译 TypeScript 并复制 UI 文件
|
||
* 3. 打包成 ZIP 文件
|
||
* 4. 支持增量打包(使用缓存的 Electron)
|
||
*/
|
||
|
||
import { existsSync, mkdirSync, rmSync, writeFileSync, readFileSync, cpSync } from 'fs';
|
||
import { join } from 'path';
|
||
import { execSync } from 'child_process';
|
||
import { homedir } from 'os';
|
||
|
||
// 路径配置
|
||
const rootDir = process.cwd();
|
||
const userCacheDir = join(homedir(), '.impress-asr-input', 'cache');
|
||
const electronCacheDir = join(userCacheDir, 'electron');
|
||
const releaseDir = join(rootDir, 'release');
|
||
const distDir = join(rootDir, 'dist');
|
||
|
||
// Electron 版本
|
||
const ELECTRON_VERSION = '28.3.3';
|
||
const ELECTRON_ZIP_NAME = `electron-v${ELECTRON_VERSION}-win32-x64.zip`;
|
||
const ELECTRON_ZIP_PATH = join(electronCacheDir, ELECTRON_ZIP_NAME);
|
||
const ELECTRON_URL = `https://npmmirror.com/mirrors/electron/${ELECTRON_VERSION}/${ELECTRON_ZIP_NAME}`;
|
||
|
||
// 颜色输出
|
||
const colors = {
|
||
reset: '\x1b[0m',
|
||
green: '\x1b[32m',
|
||
yellow: '\x1b[33m',
|
||
blue: '\x1b[34m',
|
||
red: '\x1b[31m',
|
||
};
|
||
|
||
function log(color, message) {
|
||
console.log(`${color}${message}${colors.reset}`);
|
||
}
|
||
|
||
/**
|
||
* 创建必要的目录
|
||
*/
|
||
function ensureDirs() {
|
||
log(colors.blue, '📁 创建目录...');
|
||
if (!existsSync(userCacheDir)) {
|
||
mkdirSync(userCacheDir, { recursive: true });
|
||
log(colors.green, ` ✅ 缓存目录:${userCacheDir}`);
|
||
}
|
||
if (!existsSync(electronCacheDir)) {
|
||
mkdirSync(electronCacheDir, { recursive: true });
|
||
}
|
||
if (!existsSync(releaseDir)) {
|
||
mkdirSync(releaseDir, { recursive: true });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 下载 Electron
|
||
*/
|
||
function downloadElectron() {
|
||
if (existsSync(ELECTRON_ZIP_PATH)) {
|
||
log(colors.green, `✅ Electron 已缓存:${ELECTRON_ZIP_NAME}`);
|
||
return;
|
||
}
|
||
|
||
log(colors.yellow, `📥 下载 Electron ${ELECTRON_VERSION}...`);
|
||
log(colors.blue, ` URL: ${ELECTRON_URL}`);
|
||
|
||
try {
|
||
const proxy = process.env.http_proxy || process.env.https_proxy || '';
|
||
const curlCmd = proxy
|
||
? `curl -L -o "${ELECTRON_ZIP_PATH}" --proxy "${proxy}" "${ELECTRON_URL}"`
|
||
: `curl -L -o "${ELECTRON_ZIP_PATH}" "${ELECTRON_URL}"`;
|
||
|
||
execSync(curlCmd, { stdio: 'inherit' });
|
||
|
||
if (existsSync(ELECTRON_ZIP_PATH)) {
|
||
const size = Math.round(readFileSync(ELECTRON_ZIP_PATH).length / 1024 / 1024 * 100) / 100;
|
||
log(colors.green, `✅ 下载完成:${size}MB`);
|
||
}
|
||
} catch (error) {
|
||
log(colors.red, '❌ 下载失败,请检查网络连接或代理设置');
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 编译 TypeScript
|
||
*/
|
||
function compileTypeScript() {
|
||
log(colors.blue, '📝 编译 TypeScript...');
|
||
execSync('npm run build', { stdio: 'inherit' });
|
||
log(colors.green, '✅ 编译完成');
|
||
}
|
||
|
||
/**
|
||
* 解压 Electron
|
||
*/
|
||
function unzipElectron(outputDir) {
|
||
if (existsSync(outputDir)) {
|
||
rmSync(outputDir, { recursive: true, force: true });
|
||
}
|
||
mkdirSync(outputDir, { recursive: true });
|
||
|
||
log(colors.blue, '📦 解压 Electron...');
|
||
execSync(`unzip -o "${ELECTRON_ZIP_PATH}" -d "${outputDir}"`, { stdio: 'inherit' });
|
||
log(colors.green, '✅ 解压完成');
|
||
}
|
||
|
||
/**
|
||
* 复制应用文件
|
||
*/
|
||
function copyAppFiles(appDir) {
|
||
log(colors.blue, '📋 复制应用文件...');
|
||
|
||
const resourcesAppDir = join(appDir, 'resources', 'app');
|
||
mkdirSync(resourcesAppDir, { recursive: true });
|
||
|
||
// 复制 dist 目录
|
||
const distFiles = ['core', 'utils', 'ui', 'electron-main.js', 'preload.js', 'main.js', 'package.json'];
|
||
for (const file of distFiles) {
|
||
const src = join(distDir, file);
|
||
const dest = join(resourcesAppDir, file);
|
||
|
||
if (existsSync(src)) {
|
||
cpSync(src, dest, { recursive: true });
|
||
log(colors.green, ` ✅ ${file}`);
|
||
}
|
||
}
|
||
|
||
// 复制 node_modules
|
||
const nodeModulesDir = join(resourcesAppDir, 'node_modules');
|
||
mkdirSync(nodeModulesDir, { recursive: true });
|
||
|
||
const deps = ['onnxruntime-web', 'clipboardy', 'commander'];
|
||
for (const dep of deps) {
|
||
const src = join(rootDir, 'node_modules', dep);
|
||
const dest = join(nodeModulesDir, dep);
|
||
if (existsSync(src)) {
|
||
cpSync(src, dest, { recursive: true });
|
||
log(colors.green, ` ✅ node_modules/${dep}`);
|
||
}
|
||
}
|
||
|
||
// 创建空的 models 目录
|
||
mkdirSync(join(resourcesAppDir, 'models'), { recursive: true });
|
||
log(colors.green, ' ✅ models/');
|
||
}
|
||
|
||
/**
|
||
* 打包成 ZIP
|
||
*/
|
||
function createZip(packageName) {
|
||
log(colors.blue, '📦 打包 ZIP...');
|
||
|
||
const zipPath = join(releaseDir, packageName);
|
||
const appName = 'impress-asr-input-win-x64';
|
||
|
||
execSync(`zip -rq "${zipPath}" "${appName}"`, {
|
||
cwd: releaseDir,
|
||
stdio: 'inherit'
|
||
});
|
||
|
||
const size = Math.round(readFileSync(zipPath).length / 1024 / 1024 * 100) / 100;
|
||
log(colors.green, `✅ 打包完成:${packageName} (${size}MB)`);
|
||
}
|
||
|
||
/**
|
||
* 清理临时目录
|
||
*/
|
||
function cleanup() {
|
||
log(colors.blue, '🧹 清理临时文件...');
|
||
const tempDir = join(releaseDir, 'impress-asr-input-win-x64');
|
||
if (existsSync(tempDir)) {
|
||
rmSync(tempDir, { recursive: true, force: true });
|
||
}
|
||
log(colors.green, '✅ 清理完成');
|
||
}
|
||
|
||
/**
|
||
* 主函数
|
||
*/
|
||
function main() {
|
||
console.log('');
|
||
log(colors.green, '╔════════════════════════════════════════════╗');
|
||
log(colors.green, '║ Impress ASR Input - Windows x64 打包工具 ║');
|
||
log(colors.green, '╚════════════════════════════════════════════╝');
|
||
console.log('');
|
||
|
||
try {
|
||
// 1. 创建目录
|
||
ensureDirs();
|
||
|
||
// 2. 下载 Electron
|
||
downloadElectron();
|
||
|
||
// 3. 编译 TypeScript
|
||
compileTypeScript();
|
||
|
||
// 4. 解压 Electron 到临时目录
|
||
const tempDir = join(releaseDir, 'impress-asr-input-win-x64');
|
||
unzipElectron(tempDir);
|
||
|
||
// 5. 复制应用文件
|
||
copyAppFiles(tempDir);
|
||
|
||
// 6. 打包
|
||
const version = '0.1.0';
|
||
const packageName = `Impress_ASR_Input-${version}-win-x64.zip`;
|
||
createZip(packageName);
|
||
|
||
// 7. 清理
|
||
cleanup();
|
||
|
||
console.log('');
|
||
log(colors.green, '═══════════════════════════════════════');
|
||
log(colors.green, '✅ Windows x64 版本打包完成!');
|
||
log(colors.green, '═══════════════════════════════════════');
|
||
log(colors.blue, `📦 输出文件:release/${packageName}`);
|
||
log(colors.blue, `💾 缓存目录:${userCacheDir}`);
|
||
console.log('');
|
||
|
||
} catch (error) {
|
||
console.log('');
|
||
log(colors.red, '❌ 打包失败!');
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 运行
|
||
main();
|