2025-07-20 14:22:04 +07:00
|
|
|
import { execSync } from "child_process";
|
|
|
|
import fs from "fs";
|
|
|
|
import path from "path";
|
2025-07-22 10:55:02 +07:00
|
|
|
import { minify } from "terser";
|
2025-07-20 14:22:04 +07:00
|
|
|
import url from "url";
|
2025-07-20 15:03:43 +07:00
|
|
|
import syncVersion from "./syncVersion.js";
|
2025-07-20 14:22:04 +07:00
|
|
|
|
|
|
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
|
|
const frontendDir = path.join(__dirname, "frontend");
|
|
|
|
const distDir = path.join(frontendDir, "dist");
|
|
|
|
const srcDir = path.join(__dirname, "src");
|
|
|
|
const iconDir = path.join(__dirname, "icons");
|
|
|
|
const releaseDir = path.join(__dirname, "extension-release");
|
|
|
|
|
2025-07-20 15:03:43 +07:00
|
|
|
const run = (cmd, cwd) => {
|
2025-07-20 14:22:04 +07:00
|
|
|
console.log(`🛠️ Running: ${cmd}`);
|
|
|
|
execSync(cmd, { cwd, stdio: "inherit" });
|
2025-07-20 15:03:43 +07:00
|
|
|
};
|
2025-07-20 14:22:04 +07:00
|
|
|
|
2025-07-20 15:03:43 +07:00
|
|
|
const copyDir = async (src, dest) => {
|
2025-07-20 14:22:04 +07:00
|
|
|
await fs.promises.mkdir(dest, { recursive: true });
|
|
|
|
await fs.promises.cp(src, dest, {
|
|
|
|
recursive: true,
|
|
|
|
force: true,
|
|
|
|
filter: (src) => !src.endsWith(".map"),
|
|
|
|
});
|
2025-07-20 15:03:43 +07:00
|
|
|
};
|
|
|
|
|
2025-07-22 10:55:02 +07:00
|
|
|
const minifyJS = async (jsContent) => {
|
|
|
|
try {
|
|
|
|
const result = await minify(jsContent, {
|
|
|
|
compress: {
|
|
|
|
drop_console: false, // Keep console logs for debugging
|
|
|
|
drop_debugger: true,
|
|
|
|
pure_funcs: ["console.debug"],
|
|
|
|
},
|
|
|
|
mangle: {
|
|
|
|
reserved: ["chrome"], // Don't mangle chrome API
|
|
|
|
},
|
|
|
|
});
|
|
|
|
return result.code;
|
|
|
|
} catch (error) {
|
|
|
|
console.warn("⚠️ Minification failed, using original:", error.message);
|
|
|
|
return jsContent;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Copy and minify JavaScript files from src directory
|
|
|
|
const copyAndMinifySrcFiles = async (src, dest) => {
|
|
|
|
await fs.promises.mkdir(dest, { recursive: true });
|
|
|
|
|
|
|
|
const entries = await fs.promises.readdir(src, { withFileTypes: true });
|
|
|
|
|
|
|
|
for (const entry of entries) {
|
|
|
|
const srcPath = path.join(src, entry.name);
|
|
|
|
const destPath = path.join(dest, entry.name);
|
|
|
|
|
|
|
|
if (entry.isDirectory()) {
|
|
|
|
await copyAndMinifySrcFiles(srcPath, destPath);
|
|
|
|
} else if (entry.name.endsWith(".js")) {
|
|
|
|
// Minify JavaScript files
|
|
|
|
console.log(`🗜️ Minifying ${entry.name}...`);
|
|
|
|
const content = await fs.promises.readFile(srcPath, "utf8");
|
|
|
|
const originalSize = Buffer.byteLength(content, "utf8");
|
|
|
|
const minified = await minifyJS(content, entry.name);
|
|
|
|
const minifiedSize = Buffer.byteLength(minified, "utf8");
|
|
|
|
const savings = (((originalSize - minifiedSize) / originalSize) * 100).toFixed(1);
|
|
|
|
console.log(
|
|
|
|
` 📊 ${entry.name}: ${originalSize} → ${minifiedSize} bytes (${savings}% smaller)`
|
|
|
|
);
|
|
|
|
await fs.promises.writeFile(destPath, minified, "utf8");
|
|
|
|
} else {
|
|
|
|
// Copy other files as-is
|
|
|
|
await fs.promises.copyFile(srcPath, destPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2025-07-20 15:03:43 +07:00
|
|
|
const main = async () => {
|
|
|
|
await syncVersion();
|
2025-07-20 14:22:04 +07:00
|
|
|
|
|
|
|
console.log("🚀 Starting extension build...");
|
|
|
|
|
|
|
|
// 1. Install frontend deps if needed
|
|
|
|
if (!fs.existsSync(path.join(frontendDir, "node_modules"))) {
|
|
|
|
console.log("📦 node_modules not found. Running npm install...");
|
|
|
|
run("npm install", frontendDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. Build frontend
|
|
|
|
console.log("📦 Building frontend...");
|
|
|
|
run("npm run build", frontendDir);
|
|
|
|
|
|
|
|
// 3. Clean release folder
|
|
|
|
if (fs.existsSync(releaseDir)) {
|
|
|
|
console.log("🧹 Cleaning existing extension-release folder...");
|
|
|
|
await fs.promises.rm(releaseDir, { recursive: true, force: true });
|
|
|
|
}
|
|
|
|
await fs.promises.mkdir(releaseDir);
|
|
|
|
|
2025-07-22 10:55:02 +07:00
|
|
|
// 4. Copy and minify src files
|
|
|
|
console.log("📦 Copying and minifying src files...");
|
|
|
|
await copyAndMinifySrcFiles(srcDir, releaseDir);
|
2025-07-20 14:22:04 +07:00
|
|
|
|
|
|
|
// 5. Copy frontend dist files to release (merged at root)
|
|
|
|
console.log("📦 Copying frontend dist files to extension-release...");
|
|
|
|
await copyDir(distDir, releaseDir);
|
|
|
|
|
|
|
|
// 6. Copy icon directory to release (merged at root)
|
|
|
|
console.log("📦 Copying icon directory to extension-release...");
|
|
|
|
await copyDir(iconDir, path.join(releaseDir, "icons"));
|
|
|
|
|
|
|
|
console.log("✅ Build complete! extension-release ready.");
|
2025-07-20 15:03:43 +07:00
|
|
|
};
|
2025-07-20 14:22:04 +07:00
|
|
|
|
|
|
|
main().catch((e) => {
|
|
|
|
console.error("❌ Build failed:", e);
|
|
|
|
process.exit(1);
|
|
|
|
});
|