hyperchat/scripts/build.mjs

320 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
import { execSync } from 'child_process';
import { copyFileSync, mkdirSync, existsSync, readFileSync, writeFileSync, rmSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = join(__dirname, '..');
// 辅助函数:执行命令
function exec(command, options = {}) {
console.log(`\n📦 执行: ${command}`);
try {
execSync(command, { stdio: 'inherit', cwd: rootDir, ...options });
} catch (error) {
console.error(`❌ 命令失败: ${command}`);
process.exit(1);
}
}
// 辅助函数:确保目录存在
function ensureDir(dir) {
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}
}
// 辅助函数:读取和写入 JSON
function readJSON(path) {
return JSON.parse(readFileSync(path, 'utf-8'));
}
function writeJSON(path, data) {
writeFileSync(path, JSON.stringify(data, null, 2));
}
// 获取命令行参数
const args = process.argv.slice(2);
const command = args[0];
// 构建任务
const tasks = {
// 清理所有构建产物
clean() {
console.log('🧹 清理构建产物...');
const dirs = [
'packages/web/build',
'packages/web/dist',
'packages/core/dist',
'packages/core/web-build',
'packages/electron/dist',
'packages/electron/web-build'
];
dirs.forEach(dir => {
const path = join(rootDir, dir);
if (existsSync(path)) {
rmSync(path, { recursive: true, force: true });
console.log(` ✅ 已删除: ${dir}`);
}
});
},
// 构建 Web 前端
async buildWeb() {
console.log('\n🌐 构建 Web 前端...');
exec('npm run build', { cwd: join(rootDir, 'packages/web') });
},
// 构建 Shared 包
async buildShared() {
console.log('\n📦 构建 Shared 包...');
exec('npm run build', { cwd: join(rootDir, 'packages/shared') });
},
// 构建 Shared 包 (用于发布)
async buildSharedForPublish() {
console.log('\n📦 构建 Shared 包 (发布版)...');
const sharedDir = join(rootDir, 'packages/shared');
// 先构建
await tasks.buildShared();
// 处理 package.json用于发布
const pkgPath = join(sharedDir, 'package.json');
let pkg = readJSON(pkgPath);
// 更新版本号
const rootPkg = readJSON(join(rootDir, 'package.json'));
pkg.version = rootPkg.version;
writeJSON(pkgPath, pkg);
console.log(' ✅ 已处理 Shared 包发布配置');
},
// 构建 CoreNode.js 核心)
async buildCore() {
console.log('\n🎯 构建 Core 包...');
const coreDir = join(rootDir, 'packages/core');
const distDir = join(coreDir, 'dist');
// 创建输出目录
ensureDir(distDir);
// 先确保 Web 已构建
if (!existsSync(join(rootDir, 'packages/web/build'))) {
await tasks.buildWeb();
}
// 使用完整构建流程包含web构建
exec('npm run build:full', { cwd: coreDir });
// 复制必要文件
const filesToCopy = ['README.md'];
filesToCopy.forEach(file => {
const src = join(rootDir, file);
const dest = join(distDir, file);
if (existsSync(src)) {
copyFileSync(src, dest);
console.log(` ✅ 复制: ${file}`);
}
});
// 处理 package.json用于发布
if (args.includes('--publish')) {
const corePkgPath = join(coreDir, 'package.json');
let pkg = readJSON(corePkgPath);
// 更新版本号
const rootPkg = readJSON(join(rootDir, 'package.json'));
pkg.version = rootPkg.version;
// 替换 file: 依赖为实际的包版本
if (pkg.dependencies && pkg.dependencies['@dadigua/hyperchat-shared']) {
pkg.dependencies['@dadigua/hyperchat-shared'] = `^${rootPkg.version}`;
console.log(` ✅ 更新 @dadigua/hyperchat-shared 依赖版本: ^${rootPkg.version}`);
}
writeJSON(corePkgPath, pkg);
console.log(' ✅ 已处理 Core 包发布配置');
}
},
// 构建 Electron
async buildElectron() {
console.log('\n💻 构建 Electron 应用...');
const electronDir = join(rootDir, 'packages/electron');
// 先确保 Web 已构建
if (!existsSync(join(rootDir, 'packages/web/build'))) {
await tasks.buildWeb();
}
// 使用 Electron 包的完整构建流程
exec('npm run build:electron', { cwd: electronDir });
},
// 构建所有
async buildAll() {
console.log('🚀 开始完整构建...\n');
// 清理
tasks.clean();
// 构建各包 (不再需要shared使用路径别名替换)
await tasks.buildCore(); // Core 构建现在包含web构建
await tasks.buildElectron();
console.log('\n✨ 所有构建已完成!');
},
// 发布准备:构建并配置发布用的包
async buildForPublish() {
console.log('📦 准备发布构建...\n');
// 清理
tasks.clean();
// 构建 core 包 (发布版)
args.push('--publish'); // 确保传递 --publish 参数
await tasks.buildCore();
console.log('\n✨ 发布构建已完成!');
console.log('\n📝 下一步:');
console.log('1. 运行: npm run publish:core');
},
// 发布 core 包
async publishCore() {
console.log('📤 发布 Core 包...');
const coreDir = join(rootDir, 'packages/core');
// 检查是否已经构建
if (!existsSync(join(coreDir, 'dist'))) {
console.log('⚠️ 检测到 Core 包未构建,先进行构建...');
if (!args.includes('--publish')) {
args.push('--publish'); // 确保传递 --publish 参数
}
await tasks.buildCore();
}
const publishTag = process.env.NPM_PUBLISH_TAG || 'latest';
const tagFlag = publishTag === 'latest' ? '' : ` --tag ${publishTag}`;
console.log(`📦 发布标签: ${publishTag}`);
exec(`npm publish --access public${tagFlag}`, { cwd: coreDir });
console.log('✅ Core 包发布完成!');
},
// 完整发布流程
async publishAll() {
console.log('🚀 开始完整发布流程...\n');
// 1. 构建发布版本
await tasks.buildForPublish();
// 2. 发布 core 包
await tasks.publishCore();
console.log('\n🎉 Core 包发布完成!');
},
// 开发模式
dev() {
const target = args[1] || 'web';
console.log(`🔧 启动开发模式: ${target}`);
switch (target) {
case 'shared':
exec('npm run dev', { cwd: join(rootDir, 'packages/shared') });
break;
case 'web':
exec('npm run start', { cwd: join(rootDir, 'packages/web') });
break;
case 'core':
exec('npm run start', { cwd: join(rootDir, 'packages/core') });
break;
case 'cli':
exec('npm run start', { cwd: join(rootDir, 'packages/cli') });
break;
case 'electron':
exec('npm run start', { cwd: join(rootDir, 'packages/electron') });
break;
case 'all':
// 使用 concurrently 同时运行多个开发服务器
exec('npx concurrently "npm run start --prefix packages/web" "npm run start --prefix packages/core"');
break;
default:
console.error(`❌ 未知的开发目标: ${target}`);
console.log('可用选项: shared, web, core, cli, electron, all');
process.exit(1);
}
},
// 帮助信息
help() {
console.log(`
HyperChat 构建脚本
使用方法:
node scripts/build.mjs <command> [options]
构建命令:
clean 清理所有构建产物
buildWeb 构建 Web 前端
buildCore 构建 Core 包 (包含Web前端)
buildElectron 构建 Electron 应用
buildAll 构建所有包
buildForPublish 构建Core包 (发布版)
发布命令:
publishCore 发布 Core 包到 npm
publishAll 完整发布流程 (推荐)
开发命令:
dev [target] 启动开发模式 (shared/web/core/cli/electron/all)
help 显示此帮助信息
选项:
--publish 为发布准备 Core 包(处理 package.json
示例:
node scripts/build.mjs buildAll
node scripts/build.mjs dev web
node scripts/build.mjs buildForPublish
node scripts/build.mjs publishCore
发布流程:
1. node scripts/build.mjs publishAll # 推荐:一键发布
或者分步执行:
2a. node scripts/build.mjs buildForPublish
2b. node scripts/build.mjs publishCore
`);
}
};
// 执行命令
const taskName = command || 'help';
const task = tasks[taskName];
if (task) {
try {
const result = task();
if (result && typeof result.catch === 'function') {
result.catch(error => {
console.error('❌ 构建失败:', error);
process.exit(1);
});
}
} catch (error) {
console.error('❌ 构建失败:', error);
process.exit(1);
}
} else {
console.error(`❌ 未知命令: ${taskName}`);
tasks.help();
process.exit(1);
}