#!/usr/bin/env node /** * 版本号同步脚本 * * 功能:从 package.json 读取版本号,自动同步到: * 1. manifest.json(Chrome 扩展要求) * 2. src/shared/version.ts(运行时常量) * * 触发时机: * - pnpm run build 之前(prebuild hook) * - pnpm run dev 之前(predev hook) * * 使用方式: * - 自动:通过 pnpm scripts 自动触发 * - 手动:pnpm run sync:version */ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; // ESM 环境下获取 __dirname const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 项目根目录 const ROOT_DIR = path.resolve(__dirname, '..'); /** * 读取 JSON 文件 */ function readJSON(filePath) { const fullPath = path.resolve(ROOT_DIR, filePath); const content = fs.readFileSync(fullPath, 'utf-8'); return JSON.parse(content); } /** * 写入 JSON 文件(格式化) */ function writeJSON(filePath, data) { const fullPath = path.resolve(ROOT_DIR, filePath); const content = JSON.stringify(data, null, 2) + '\n'; fs.writeFileSync(fullPath, content, 'utf-8'); } /** * 写入文本文件 */ function writeText(filePath, content) { const fullPath = path.resolve(ROOT_DIR, filePath); // 确保目录存在 const dir = path.dirname(fullPath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } fs.writeFileSync(fullPath, content, 'utf-8'); } /** * 主执行逻辑 */ function syncVersion() { console.log('🔄 Starting version synchronization...\n'); // 1. 读取 package.json 中的版本号 const packageJson = readJSON('package.json'); const version = packageJson.version; if (!version) { console.error('❌ Error: No version found in package.json'); process.exit(1); } console.log(`📦 Source version from package.json: ${version}`); // 2. 同步到 manifest.json try { const manifest = readJSON('manifest.json'); const oldManifestVersion = manifest.version; manifest.version = version; writeJSON('manifest.json', manifest); if (oldManifestVersion !== version) { console.log(`✅ manifest.json: ${oldManifestVersion} → ${version}`); } else { console.log(`✓ manifest.json: ${version} (unchanged)`); } } catch (error) { console.error('❌ Error syncing manifest.json:', error.message); process.exit(1); } // 3. 生成 src/shared/version.ts try { const versionTsContent = `/** * Application Version Constants * * ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY * * This file is automatically generated by scripts/sync-version.js * Source of truth: package.json "version" field * * To update version: * 1. Edit version in package.json * 2. Run: pnpm run sync:version (or automatically via prebuild/predev) * * Generated at: ${new Date().toISOString()} */ /** * Application version number (e.g., "0.1.0") */ export const APP_VERSION = '${version}' as const; /** * Application version with 'v' prefix (e.g., "v0.1.0") * Commonly used for display purposes */ export const APP_VERSION_WITH_PREFIX = 'v${version}' as const; /** * Parse version into components */ export const VERSION_PARTS = { major: ${version.split('.')[0] || 0}, minor: ${version.split('.')[1] || 0}, patch: ${version.split('.')[2] || 0}, } as const; `; writeText('src/shared/version.ts', versionTsContent); console.log(`✅ src/shared/version.ts: Generated with version ${version}`); } catch (error) { console.error('❌ Error generating version.ts:', error.message); process.exit(1); } console.log('\n✨ Version synchronization completed successfully!\n'); } // 执行同步 try { syncVersion(); } catch (error) { console.error('\n❌ Fatal error:', error.message); process.exit(1); }