feat: enforce frontend quality guardrails
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
assertBundleBudget,
|
||||
getInitialAssetFiles,
|
||||
getLazyRouteAssetSizes,
|
||||
INITIAL_BUNDLE_BUDGET_BYTES,
|
||||
measureAssets,
|
||||
} from "./bundle-budget.mjs";
|
||||
|
||||
const manifest = {
|
||||
"index.html": {
|
||||
file: "assets/entry.js",
|
||||
isEntry: true,
|
||||
imports: ["_shared"],
|
||||
dynamicImports: ["src/pages/account/ui/AccountPage.tsx"],
|
||||
},
|
||||
_shared: { file: "assets/shared.js", imports: ["_runtime"] },
|
||||
_runtime: { file: "assets/runtime.js" },
|
||||
"src/pages/account/ui/AccountPage.tsx": {
|
||||
file: "assets/account.js",
|
||||
isDynamicEntry: true,
|
||||
src: "src/pages/account/ui/AccountPage.tsx",
|
||||
},
|
||||
"src/app/routes/ProtectedLayout.tsx": {
|
||||
file: "assets/protected-layout.js",
|
||||
isDynamicEntry: true,
|
||||
src: "src/app/routes/ProtectedLayout.tsx",
|
||||
},
|
||||
};
|
||||
|
||||
const sizes = new Map([
|
||||
["assets/entry.js", 200 * 1024],
|
||||
["assets/shared.js", 175 * 1024],
|
||||
["assets/runtime.js", 100 * 1024],
|
||||
["assets/account.js", 250 * 1024],
|
||||
["assets/protected-layout.js", 50 * 1024],
|
||||
]);
|
||||
|
||||
test("measures only the eager import graph of the entry bundle", () => {
|
||||
const assets = getInitialAssetFiles(manifest);
|
||||
assert.deepEqual(assets, [
|
||||
"assets/entry.js",
|
||||
"assets/shared.js",
|
||||
"assets/runtime.js",
|
||||
]);
|
||||
assert.equal(
|
||||
measureAssets(assets, (asset) => sizes.get(asset)),
|
||||
475 * 1024,
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects an initial bundle above the configured budget", () => {
|
||||
assert.throws(
|
||||
() => assertBundleBudget(INITIAL_BUNDLE_BUDGET_BYTES + 1),
|
||||
/JavaScript payload/,
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects malformed manifests and lazy-route size regressions", () => {
|
||||
assert.throws(() => getInitialAssetFiles({}), /entry/);
|
||||
assert.deepEqual(
|
||||
getLazyRouteAssetSizes(manifest, (asset) => sizes.get(asset)),
|
||||
{
|
||||
"src/app/routes/ProtectedLayout.tsx": 50 * 1024,
|
||||
"src/pages/account/ui/AccountPage.tsx": 250 * 1024,
|
||||
},
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
getLazyRouteAssetSizes(manifest, (asset) => sizes.get(asset), {
|
||||
"src/app/routes/ProtectedLayout.tsx": 50 * 1024,
|
||||
"src/pages/account/ui/AccountPage.tsx": 249 * 1024,
|
||||
}),
|
||||
/route chunk/,
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
getLazyRouteAssetSizes(manifest, (asset) => sizes.get(asset), {
|
||||
"src/pages/account/ui/AccountPage.tsx": 250 * 1024,
|
||||
}),
|
||||
/Missing baseline/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user