From afca066833c5844e24cfe3b6eb0d1c97d216facf Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Wed, 15 Jul 2026 21:22:28 +0900 Subject: [PATCH] fix(dev): clarify frontend chunk comparisons --- .github/scripts/frontend-js-size.mts | 8 +++++++- .github/scripts/frontend-js-size.test.mts | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/scripts/frontend-js-size.mts b/.github/scripts/frontend-js-size.mts index b4a61e659a..38c6fa07e9 100644 --- a/.github/scripts/frontend-js-size.mts +++ b/.github/scripts/frontend-js-size.mts @@ -414,6 +414,12 @@ function compareChunkComparisonRows(a: ReturnType || a.name.localeCompare(b.name); } +function chunkFileDisplay(row: ReturnType[number]) { + if (row.beforeFile == null) return row.afterFile ?? ''; + if (row.afterFile == null || row.beforeFile === row.afterFile) return row.beforeFile; + return `${row.beforeFile} → ${row.afterFile}`; +} + function chunkMarkdownTable( rows: ReturnType, total?: { beforeSize: number; afterSize: number }, @@ -437,7 +443,7 @@ function chunkMarkdownTable( if (hasSummaryRow && rows.length > 0) lines.push('| | | | | |'); for (const row of rows) { - const chunkFile = row.beforeFile ?? row.afterFile ?? ''; + const chunkFile = chunkFileDisplay(row); if (row.changeType === 'added') { lines.push(`|
\`${escapeCell(row.name)}\` \`${escapeCell(chunkFile)}\`
| ${util.formatBytes(row.beforeSize)} | ${util.formatBytes(row.afterSize)} | ${util.calcAndFormatDeltaBytes(row.beforeSize, row.afterSize, 1000)} | $\\color{orange}{\\text{( + )}}$ |`); } else if (row.changeType === 'removed') { diff --git a/.github/scripts/frontend-js-size.test.mts b/.github/scripts/frontend-js-size.test.mts index 51b71c075f..3688948e94 100644 --- a/.github/scripts/frontend-js-size.test.mts +++ b/.github/scripts/frontend-js-size.test.mts @@ -83,3 +83,25 @@ test('groups generated chunks while preserving full and startup totals', async t assert.match(report, /`src\/_boot_\.ts`<\/summary>/); assert.match(report, /`vue`<\/summary>/); }); + +test('fails instead of overwriting duplicate stable chunk keys', async t => { + const duplicateVue = fixture('before', 'dist', { entry: 100, generatedA: 10, generatedB: 20, vue: 40, i18n: 50 }); + duplicateVue.manifest._vueDuplicate = { file: 'scripts/vue-duplicate-before.js', name: 'vue' }; + duplicateVue.sizes['scripts/vue-duplicate-before.js'] = 60; + + await assert.rejects( + runReport(t, duplicateVue, fixture('after', 'esm', { entry: 110, generatedA: 30, generatedB: 40, vue: 45, i18n: 50 })), + /Duplicate stable chunk key "named:vue".*vue-before\.js.*vue-duplicate-before\.js/, + ); +}); + +test('shows both filenames for an updated stable chunk', async t => { + const report = await runReport( + t, + fixture('before', 'dist', { entry: 100, generatedA: 10, generatedB: 20, vue: 40, i18n: 50 }), + fixture('after', 'esm', { entry: 110, generatedA: 30, generatedB: 40, vue: 45, i18n: 50 }), + ); + + assert.match(report, /`ja-JP\/entry-before\.js → ja-JP\/entry-after\.js`/); + assert.match(report, /`ja-JP\/vue-before\.js → ja-JP\/vue-after\.js`/); +});