diff --git a/.github/scripts/frontend-js-size.mts b/.github/scripts/frontend-js-size.mts index 370f49c082..db134bab79 100644 --- a/.github/scripts/frontend-js-size.mts +++ b/.github/scripts/frontend-js-size.mts @@ -456,6 +456,7 @@ function chunkMarkdownTable( ]; if (total != null) { lines.push(`| (total) | ${util.formatBytes(total.beforeSize)} | ${util.formatBytes(total.afterSize)} | ${util.calcAndFormatDeltaBytes(total.beforeSize, total.afterSize, 1000)} | ${util.calcAndFormatDeltaPercent(total.beforeSize, total.afterSize, 0.1).replaceAll('\\%', '\\\\%')} |`); + lines.push('| | | | | |'); } for (const row of rows) { @@ -468,17 +469,12 @@ function chunkMarkdownTable( lines.push(`|
\`${escapeCell(row.name)}\` \`${escapeCell(chunkFile)}\`
| ${util.formatBytes(row.beforeSize)} | ${util.formatBytes(row.afterSize)} | ${util.calcAndFormatDeltaBytes(row.beforeSize, row.afterSize, 1000)} | ${util.calcAndFormatDeltaPercent(row.beforeSize, row.afterSize, 0.1).replaceAll('\\%', '\\\\%')} |`); } } - if (hasGenerated || hasOther) lines.push('| | | | | |'); if (hasGenerated) { lines.push(`| (other generated chunks) | ${util.formatBytes(generated.beforeSize)} | ${util.formatBytes(generated.afterSize)} | ${util.calcAndFormatDeltaBytes(generated.beforeSize, generated.afterSize, 1000)} | ${util.calcAndFormatDeltaPercent(generated.beforeSize, generated.afterSize, 0.1).replaceAll('\\%', '\\\\%')} |`); } if (hasOther) { lines.push(`| (other) | ${util.formatBytes(other.beforeSize)} | ${util.formatBytes(other.afterSize)} | ${util.calcAndFormatDeltaBytes(other.beforeSize, other.afterSize, 1000)} | ${util.calcAndFormatDeltaPercent(other.beforeSize, other.afterSize, 0.1).replaceAll('\\%', '\\\\%')} |`); } - if (hasGenerated) { - lines.push(''); - lines.push(`_${generated.beforeCount} before / ${generated.afterCount} after generated chunks are grouped._`); - } return lines.join('\n'); } diff --git a/.github/scripts/frontend-js-size.test.mts b/.github/scripts/frontend-js-size.test.mts index f688ae3270..d3b3db9af6 100644 --- a/.github/scripts/frontend-js-size.test.mts +++ b/.github/scripts/frontend-js-size.test.mts @@ -91,7 +91,7 @@ test('groups generated chunks while preserving full and startup totals', async t assert.match(report, /\| \(total\) \| 220 B \| 285 B \|/); assert.equal(report.match(/\| \(other generated chunks\) \| 30 B \| 70 B \|/g)?.length, 2); - assert.equal(report.match(/_2 before \/ 2 after generated chunks are grouped\._/g)?.length, 2); + assert.doesNotMatch(report, /generated chunks are grouped/); assert.doesNotMatch(report, /`(?:dist|esm)`<\/summary>/); assert.match(report, /`src\/_boot_\.ts`<\/summary>/); assert.match(report, /`vue`<\/summary>/); @@ -114,8 +114,8 @@ test('groups small deltas at the bottom while preserving all change counts', asy assert.match(report, /Startup chunk size \(2 updated, 1 added, 1 removed\)<\/summary>/); assert.equal(report.match(/`src\/_boot_\.ts`<\/summary>/g)?.length, 2); assert.doesNotMatch(report, /`(?:vue|i18n|src\/added-small\.ts|src\/removed-small\.ts)`<\/summary>/); - assert.match(report, /\| \(total\) \| 225 B \| 276 B \|[^\n]*\n\|
`src\/_boot_\.ts`<\/summary>[^\n]*\n\| \| \| \| \| \|\n\| \(other generated chunks\) \| 30 B \| 70 B \|[^\n]*\n\| \(other\) \| 45 B \| 50 B \|/); - assert.match(report, /\| \(total\) \| 225 B \| 276 B \|[^\n]*\n\|
`src\/_boot_\.ts`<\/summary>[^\n]*\n\| \| \| \| \| \|\n\| \(other generated chunks\) \| 30 B \| 70 B \|[^\n]*\n\| \(other\) \| 95 B \| 100 B \|/); + assert.match(report, /\| \(total\) \| 225 B \| 276 B \|[^\n]*\n\| \| \| \| \| \|\n\|
`src\/_boot_\.ts`<\/summary>[^\n]*\n\| \(other generated chunks\) \| 30 B \| 70 B \|[^\n]*\n\| \(other\) \| 45 B \| 50 B \|/); + assert.match(report, /\| \(total\) \| 225 B \| 276 B \|[^\n]*\n\| \| \| \| \| \|\n\|
`src\/_boot_\.ts`<\/summary>[^\n]*\n\| \(other generated chunks\) \| 30 B \| 70 B \|[^\n]*\n\| \(other\) \| 95 B \| 100 B \|/); }); test('fails instead of overwriting duplicate stable chunk keys', async t => { @@ -224,7 +224,6 @@ test('counts an unmanifested localized JavaScript file in totals and the generat assert.match(report, /\| \(total\) \| 235 B \| 275 B \|/); assert.match(report, /\| \(other generated chunks\) \| 45 B \| 70 B \|/); - assert.match(report, /_3 before \/ 2 after generated chunks are grouped\._/); }); test('counts duplicate manifest entries for one physical output only once', async t => { @@ -238,7 +237,6 @@ test('counts duplicate manifest entries for one physical output only once', asyn ); assert.match(report, /\| \(total\) \| 220 B \| 275 B \|/); - assert.match(report, /_2 before \/ 2 after generated chunks are grouped\._/); }); test('does not count generated-aggregate-only changes as individual chunk changes', async t => { diff --git a/docs/superpowers/specs/2026-07-15-frontend-bundle-generated-chunks-design.md b/docs/superpowers/specs/2026-07-15-frontend-bundle-generated-chunks-design.md index 1cadf1f3fa..3a8c404a3e 100644 --- a/docs/superpowers/specs/2026-07-15-frontend-bundle-generated-chunks-design.md +++ b/docs/superpowers/specs/2026-07-15-frontend-bundle-generated-chunks-design.md @@ -95,9 +95,7 @@ The table starts with the existing `(total)` row. Generated chunks are rendered (other generated chunks) ``` -This row compares aggregate sizes, not individual chunk identities. Generated chunks do not participate in the updated/added/removed row counts. - -The report includes a short note stating how many generated chunks were grouped on each side. This makes the scope of the aggregate explicit without listing noisy filenames. +This row compares aggregate sizes, not individual chunk identities. Generated chunks do not participate in the updated/added/removed row counts. No additional generated-chunk count note is rendered below the table. ### Small-delta aggregation @@ -110,11 +108,13 @@ The updated/added/removed counts are calculated before small-delta rows are grou Table rows are ordered as follows: 1. `(total)`; -2. individual stable comparison rows whose absolute delta is greater than `5 B`; -3. one empty separator row, when at least one aggregate row follows; +2. one empty separator row; +3. individual stable comparison rows whose absolute delta is greater than `5 B`; 4. `(other generated chunks)`, when generated chunks exist; and 5. `(other)`, when small-delta stable chunks exist. +There is no additional separator row before the aggregate rows. If no individual stable row exists, the empty row after `(total)` is therefore immediately followed by the aggregate rows. + The existing 30-row limit applies after small-delta rows have been removed from the individual-row candidates. ### Startup chunk report @@ -165,7 +165,8 @@ Add focused fixtures or pure-function tests covering: - differing before/after filenames are rendered without attributing both sizes to one file; - deltas of exactly `5 B` are grouped into `(other)`, while `6 B` deltas remain individual; - small updated, added, and removed chunks remain included in the summary counts; -- `(other generated chunks)` and `(other)` appear below individual rows after an empty separator row; and +- an empty separator row appears immediately after `(total)`, with no additional separator before `(other generated chunks)` or `(other)`; +- no generated-chunk grouping note is rendered below the table; and - the same small-delta and ordering rules apply to the full and startup tables. Validation should include the focused tests and repository lint. No CHANGELOG entry is required because this changes developer-facing CI reporting rather than Misskey user behavior.