const fs = require('fs'); const path = require('path'); const sharp = require('sharp'); const CONTENT_DIR = path.join(__dirname, '../content/posts'); const MAX_SIZE_BYTES = 1 * 1024 * 1024; // 1MB async function processDirectory(dir) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { await processDirectory(fullPath); } else if (entry.isFile()) { const ext = path.extname(entry.name).toLowerCase(); if (['.png', '.jpg', '.jpeg'].includes(ext)) { const stats = fs.statSync(fullPath); if (stats.size > MAX_SIZE_BYTES) { console.log(`Processing large image: ${fullPath} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`); await convertToWebP(fullPath); } } } } } async function convertToWebP(filePath) { const dir = path.dirname(filePath); const ext = path.extname(filePath); const name = path.basename(filePath, ext); const newFileName = `${name}.webp`; const newFilePath = path.join(dir, newFileName); try { await sharp(filePath) .webp({ quality: 80 }) .toFile(newFilePath); console.log(`Converted to: ${newFileName}`); // Update index.md const mdPath = path.join(dir, 'index.md'); if (fs.existsSync(mdPath)) { let content = fs.readFileSync(mdPath, 'utf8'); // Replace exact filename const regex = new RegExp(escapeRegExp(path.basename(filePath)), 'g'); if (regex.test(content)) { content = content.replace(regex, newFileName); fs.writeFileSync(mdPath, content, 'utf8'); console.log(`Updated index.md reference.`); // Delete original file only if markdown was updated (safety) fs.unlinkSync(filePath); console.log(`Deleted original file.`); } else { console.warn(`Warning: Could not find reference to ${path.basename(filePath)} in index.md. Keeping original file.`); // If not found in index.md, maybe it's not used or referenced differently? // For safety, we keep it, but this defeats the purpose of space saving if it's unused. // But if it IS used but I missed the regex, deleting it breaks the site. // However, user wants to fix deployment. Unused large files should be deleted. // But I'll play safe. // Actually, let's delete it if we have the webp. // Wait, if markdown still points to png, site breaks. // So keeping it is safer. } } else { console.warn(`Warning: No index.md found in ${dir}.`); } } catch (err) { console.error(`Error converting ${filePath}:`, err); } } function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string } (async () => { console.log(`Starting image optimization in ${CONTENT_DIR}...`); if (fs.existsSync(CONTENT_DIR)) { await processDirectory(CONTENT_DIR); } else { console.error(`Directory not found: ${CONTENT_DIR}`); } console.log('Done.'); })();