Files
WRNexusJS/packages/cli/src/analyze.ts
T
Clintchiz 586a6db8ff
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s
release: WRNexusJS 0.8.0
2026-08-02 23:18:51 +05:30

90 lines
3.2 KiB
TypeScript

import { existsSync, readFileSync } from "node:fs";
import { join, resolve } from "node:path";
interface BuildReport {
frameworkVersion: string;
generatedAt: string;
adapter: string;
routes: Array<{
path: string;
source: string;
sourceBytes: number;
dynamicParams: string[];
optimization?: {
staticNodes: number;
reactiveRegions: number;
eliminatedBranches: number;
unusedState: string[];
unusedHandlers: string[];
constantProps: string[];
unusedLocalCssClasses: string[];
batchableStateUpdates: number;
memoizableComponents: string[];
preloadDependencies: string[];
serverOnlyModules: string[];
};
}>;
assets: Array<{ file: string; bytes: number }>;
measurements: Record<string, number>;
budgetViolations: Array<{ metric: string; budget: number; actual: number; overBy: number }>;
}
function bytes(value: number): string {
if (value < 1024) return `${value} B`;
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`;
return `${(value / 1024 / 1024).toFixed(2)} MB`;
}
export function runAnalyze(appRoot: string, args: string[]): boolean {
const root = resolve(appRoot);
const path = join(root, "dist", "build-report.json");
if (!existsSync(path)) {
console.error("WRN-BUILD-REPORT-MISSING: run `wrnexus build` before `wrnexus analyze`.");
return false;
}
const report = JSON.parse(readFileSync(path, "utf8")) as BuildReport;
if (args.includes("--json")) {
console.log(JSON.stringify(report, null, 2));
return report.budgetViolations.length === 0;
}
console.log(`WRNexus build analysis (${report.frameworkVersion})`);
console.log(` Generated: ${report.generatedAt}`);
console.log(` Adapter: ${report.adapter}`);
console.log(` Routes: ${report.routes.length}`);
console.log("\nMeasurements:");
for (const [metric, value] of Object.entries(report.measurements)) {
console.log(` ${metric.padEnd(18)} ${bytes(value)}`);
}
console.log("\nLargest assets:");
for (const asset of report.assets.slice(0, 12)) {
console.log(` ${bytes(asset.bytes).padStart(10)} ${asset.file}`);
}
console.log("\nCompiler optimizations:");
for (const route of report.routes.filter((item) => item.optimization)) {
const optimization = route.optimization!;
console.log(
` ${route.path}: ${optimization.staticNodes} static nodes, ${optimization.reactiveRegions} reactive regions, ${optimization.eliminatedBranches} branches removed`,
);
if (
optimization.unusedState.length ||
optimization.unusedHandlers.length ||
optimization.unusedLocalCssClasses.length
)
console.log(
` candidates: ${[...optimization.unusedState, ...optimization.unusedHandlers, ...optimization.unusedLocalCssClasses].join(", ")}`,
);
}
if (report.budgetViolations.length) {
console.log("\nBudget violations:");
for (const violation of report.budgetViolations) {
console.log(
` ✗ ${violation.metric}: ${bytes(violation.actual)} > ${bytes(violation.budget)}`,
);
}
} else {
console.log("\n ✓ No configured performance budget violations.");
}
return report.budgetViolations.length === 0;
}