feat: 添加 Windows 自动打包脚本,支持本地缓存 Electron
This commit is contained in:
parent
6681397167
commit
3e8be47295
232
scripts/build-windows.js
Normal file
232
scripts/build-windows.js
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/**
|
||||||
|
* 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();
|
||||||
Loading…
Reference in New Issue
Block a user