|
@@ -0,0 +1,161 @@
|
|
|
|
+// build-h5-smart.js - 带智能缓存的 H5 构建脚本
|
|
|
|
+const fs = require('fs');
|
|
|
|
+const path = require('path');
|
|
|
|
+const crypto = require('crypto');
|
|
|
|
+const { execSync } = require('child_process');
|
|
|
|
+const { glob } = require('glob');
|
|
|
|
+
|
|
|
|
+const CACHE_MARKER_FILE = 'dist/h5/.build-cache-marker';
|
|
|
|
+const SOURCE_PATTERNS = ['src/**/*', 'config/**/*', 'package-lock.json', '.build/h5_for_production.js'];
|
|
|
|
+
|
|
|
|
+// 计算文件哈希
|
|
|
|
+function hashFile(filePath) {
|
|
|
|
+ if (!fs.existsSync(filePath)) {
|
|
|
|
+ return '';
|
|
|
|
+ }
|
|
|
|
+ const content = fs.readFileSync(filePath);
|
|
|
|
+ return crypto.createHash('md5').update(content).digest('hex');
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 计算多个文件的组合哈希
|
|
|
|
+async function hashFiles(patterns) {
|
|
|
|
+ const hashes = [];
|
|
|
|
+
|
|
|
|
+ for (const pattern of patterns) {
|
|
|
|
+ try {
|
|
|
|
+ // 使用 glob 查找匹配的文件
|
|
|
|
+ const files = await glob(pattern, {
|
|
|
|
+ cwd: process.cwd(),
|
|
|
|
+ ignore: ['**/node_modules/**', '**/dist/**', '**/.git/**'],
|
|
|
|
+ nodir: true
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 对每个文件计算哈希
|
|
|
|
+ for (const file of files.sort()) {
|
|
|
|
+ const hash = hashFile(file);
|
|
|
|
+ if (hash) {
|
|
|
|
+ hashes.push(`${file}:${hash}`);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.warn(`警告: 无法处理模式 ${pattern}: ${error.message}`);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 将所有哈希组合成一个总哈希
|
|
|
|
+ const combined = hashes.join('\n');
|
|
|
|
+ return crypto.createHash('md5').update(combined).digest('hex');
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 检查 H5 构建缓存
|
|
|
|
+async function checkH5BuildCache() {
|
|
|
|
+ console.log('🔍 检查 H5 构建缓存...');
|
|
|
|
+
|
|
|
|
+ // 检查构建产物是否存在
|
|
|
|
+ if (!fs.existsSync('dist/h5')) {
|
|
|
|
+ console.log('❌ 构建产物不存在');
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 检查缓存标记文件
|
|
|
|
+ if (!fs.existsSync(CACHE_MARKER_FILE)) {
|
|
|
|
+ console.log('❌ 缓存标记文件不存在');
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 读取缓存的哈希值
|
|
|
|
+ const cachedHash = fs.readFileSync(CACHE_MARKER_FILE, 'utf8').trim();
|
|
|
|
+
|
|
|
|
+ // 计算当前源文件的哈希值
|
|
|
|
+ console.log('📊 计算源文件哈希...');
|
|
|
|
+ const currentHash = await hashFiles(SOURCE_PATTERNS);
|
|
|
|
+
|
|
|
|
+ console.log(` 缓存哈希: ${cachedHash.substring(0, 8)}...`);
|
|
|
|
+ console.log(` 当前哈希: ${currentHash.substring(0, 8)}...`);
|
|
|
|
+
|
|
|
|
+ if (cachedHash === currentHash) {
|
|
|
|
+ console.log('✅ H5 构建缓存命中!');
|
|
|
|
+ return true;
|
|
|
|
+ } else {
|
|
|
|
+ console.log('❌ 源文件已更改,需要重新构建');
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('⚠️ 检查缓存时出错:', error.message);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 保存构建缓存标记
|
|
|
|
+async function saveBuildCacheMarker() {
|
|
|
|
+ console.log('💾 保存构建缓存标记...');
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ const currentHash = await hashFiles(SOURCE_PATTERNS);
|
|
|
|
+
|
|
|
|
+ // 确保目录存在
|
|
|
|
+ const markerDir = path.dirname(CACHE_MARKER_FILE);
|
|
|
|
+ if (!fs.existsSync(markerDir)) {
|
|
|
|
+ fs.mkdirSync(markerDir, { recursive: true });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fs.writeFileSync(CACHE_MARKER_FILE, currentHash);
|
|
|
|
+ console.log(`✅ 缓存标记已保存: ${currentHash.substring(0, 8)}...`);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('⚠️ 保存缓存标记时出错:', error.message);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 执行 H5 构建
|
|
|
|
+function buildH5() {
|
|
|
|
+ console.log('🔨 开始构建 H5...');
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ execSync('node .build/h5_for_production.js', {
|
|
|
|
+ stdio: 'inherit',
|
|
|
|
+ cwd: process.cwd()
|
|
|
|
+ });
|
|
|
|
+ console.log('✅ H5 构建完成');
|
|
|
|
+ return true;
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('❌ H5 构建失败:', error.message);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 主函数
|
|
|
|
+async function main() {
|
|
|
|
+ console.log('🚀 智能 H5 构建系统');
|
|
|
|
+ console.log('====================\n');
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 检查缓存
|
|
|
|
+ const cacheHit = await checkH5BuildCache();
|
|
|
|
+
|
|
|
|
+ if (cacheHit) {
|
|
|
|
+ console.log('\n🎉 使用缓存的构建产物,跳过构建步骤');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 需要重新构建
|
|
|
|
+ console.log('\n📦 执行 H5 构建...');
|
|
|
|
+ const success = buildH5();
|
|
|
|
+
|
|
|
|
+ if (success) {
|
|
|
|
+ // 保存新的缓存标记
|
|
|
|
+ await saveBuildCacheMarker();
|
|
|
|
+ console.log('\n🎉 构建成功!');
|
|
|
|
+ } else {
|
|
|
|
+ console.error('\n❌ 构建失败');
|
|
|
|
+ process.exit(1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('❌ 错误:', error.message);
|
|
|
|
+ process.exit(1);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 运行
|
|
|
|
+main();
|