123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- // 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();
|