rebuild-and-verify.mjs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env node
  2. /**
  3. * 一键重打包脚本:清理旧进程 + 重新打包 + 快速验证
  4. * 用法:node scripts/rebuild-and-verify.mjs [--target D:\qiwei-training]
  5. */
  6. import { spawnSync } from 'node:child_process';
  7. import path from 'node:path';
  8. import { fileURLToPath } from 'node:url';
  9. const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
  10. const DEFAULT_TARGET = 'D:\\qiwei-training';
  11. function parseArgs(argv = process.argv.slice(2)) {
  12. const targetIndex = argv.indexOf('--target');
  13. const target = targetIndex >= 0 && argv[targetIndex + 1]
  14. ? argv[targetIndex + 1]
  15. : DEFAULT_TARGET;
  16. return { target: path.resolve(target) };
  17. }
  18. function run(command, args, options = {}) {
  19. const base = { cwd: ROOT, encoding: 'utf8', stdio: 'inherit', ...options };
  20. return spawnSync(command, args, base);
  21. }
  22. function step(title, fn) {
  23. console.log(`\n[${title}]`);
  24. const start = Date.now();
  25. const result = fn();
  26. const elapsed = ((Date.now() - start) / 1000).toFixed(1);
  27. console.log(`✓ ${title} (${elapsed}s)`);
  28. return result;
  29. }
  30. async function main() {
  31. const options = parseArgs();
  32. console.log('\n=== 企微培训包一键重打包 ===');
  33. console.log(`目标目录: ${options.target}\n`);
  34. // 步骤 1:停止已有进程
  35. step('停止旧进程', () => {
  36. if (process.platform === 'win32') {
  37. // 停止 qiwei-workbench.exe
  38. run('taskkill', ['/F', '/IM', 'qiwei-workbench.exe'], { stdio: 'pipe' });
  39. // 等待端口释放
  40. const start = Date.now();
  41. while (Date.now() - start < 3000) {
  42. const check = run('netstat', ['-ano'], { stdio: 'pipe' });
  43. if (!check.stdout || !check.stdout.includes(':4320')) break;
  44. }
  45. } else {
  46. run('pkill', ['-f', 'qiwei-workbench']);
  47. }
  48. });
  49. // 步骤 2:执行打包
  50. step('执行打包', () => {
  51. const result = run('node', [
  52. 'scripts/build-training-package.mjs',
  53. '--outdir', options.target
  54. ]);
  55. if (result.status !== 0) {
  56. throw new Error('打包失败');
  57. }
  58. });
  59. // 步骤 3:快速验证
  60. if (process.platform === 'win32') {
  61. step('快速验证', () => {
  62. const result = run('powershell', [
  63. '-ExecutionPolicy', 'Bypass',
  64. '-File', 'scripts/quick-verify-training-package.ps1',
  65. options.target
  66. ], { stdio: 'pipe' });
  67. // 15 秒后自动停止
  68. setTimeout(() => {
  69. run('taskkill', ['/F', '/IM', 'qiwei-workbench.exe'], { stdio: 'pipe' });
  70. }, 15000);
  71. return result;
  72. });
  73. }
  74. console.log('\n=== 重打包完成 ===');
  75. console.log(`\n产物目录: ${options.target}`);
  76. console.log('下一步: 测试或打包为 ZIP 分发\n');
  77. }
  78. main().catch(error => {
  79. console.error('\n✗ 重打包失败:', error.message);
  80. process.exit(1);
  81. });