bundle-analyzer: add table view to single-build analyzer (#93523)

Extends the view toggle (introduced in the previous PR for compare mode)
to single-build mode as well. The table view lists all sources for the
selected route with sizes and env badges. Internally it reuses
`DiffTable` in `mode="single"` by diffing the build against itself,
which produces an all-`identical` summary — this keeps a single
source-listing implementation regardless of mode.

<!-- NEXT_JS_LLM_PR -->

Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Will Binns-Smith <755844+wbinnssmith@users.noreply.github.com>
This commit is contained in:
Will Binns-Smith
2026-09-10 12:47:56 -07:00
committed by GitHub
parent 0bdea6782d
commit 6fbba169cd
+31 -2
View File
@@ -3,6 +3,7 @@
import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
import useSWR from 'swr'
import { CompareLayout } from '@/components/compare-layout'
import { DiffTable } from '@/components/diff-table'
import { ErrorState } from '@/components/error-state'
import { Sidebar } from '@/components/sidebar'
import { TopBar, Environment, CompareView } from '@/components/top-bar'
@@ -303,6 +304,18 @@ export default function Home() {
return null
}, [analyzeData, baselineAnalyzeData, baselineSnapshot, compareFilterSource])
// In single-build (non-compare) mode the table view still wants a list
// of every source for the current route. We synthesize this by diffing
// the build against itself, which produces an all-`identical` summary
// that we feed into `<DiffTable mode="single">`. This keeps a single
// sources-listing implementation regardless of mode.
const singleSourceListing = useMemo(() => {
if (!analyzeData || baselineSnapshot) return null
return diffSources(analyzeData, analyzeData, {
filterSource: (_, index) => filterSource(index),
})
}, [analyzeData, baselineSnapshot, filterSource])
// Per-route totals for both sides, used to size the route-level diff so
// that routes whose modules changed can be reported as `changed` rather
// than `identical`. Only fetched in compare mode.
@@ -402,6 +415,21 @@ export default function Home() {
analyzerContent = (
<>
<div className="flex-1 min-w-0">
{compareView === CompareView.Table && singleSourceListing ? (
<DiffTable
summary={singleSourceListing}
useCompressed
nameHeading="Source"
mode="single"
searchQuery={searchQuery}
onRowSelect={(row) => {
if (row.sourceIndexB != null) {
setSelectedSourceIndex(row.sourceIndexB)
setFocusedSourceIndex(row.sourceIndexB)
}
}}
/>
) : (
<TreemapVisualizer
analyzeData={analyzeData}
sourceIndex={rootSourceIndex}
@@ -416,6 +444,7 @@ export default function Home() {
filterSource={filterSource}
sizeMode={SizeMode.Compressed}
/>
)}
</div>
<button
type="button"
@@ -440,7 +469,7 @@ export default function Home() {
<main className="h-screen flex flex-col bg-background">
<TopBar
hasSourceData={analyzeData != null}
showViewToggle={isCompareMode}
showViewToggle={analyzeData != null}
compareView={compareView}
onCompareViewChange={setCompareView}
selectedRoute={selectedRoute}
@@ -465,7 +494,7 @@ export default function Home() {
<div className="flex-1 flex min-h-0">{analyzerContent}</div>
{analyzeData && !isCompareMode ? (
{analyzeData && !isCompareMode && compareView === CompareView.Treemap ? (
<div className="flex-none border-t border-border bg-background px-4 py-2 h-10">
<div className="text-sm text-muted-foreground">
{hoveredNodeInfo ? (