'use client' import type React from 'react' import { CircleHelp } from 'lucide-react' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from './ui/tooltip' import { ImportChain } from '@/components/import-chain' import { Skeleton } from '@/components/ui/skeleton' import { AnalyzeData, ModulesData } from '@/lib/analyze-data' import { SpecialModule } from '@/lib/types' import { getSpecialModuleType } from '@/lib/utils' import { Badge } from './ui/badge' interface SidebarProps { sidebarWidth: number analyzeData: AnalyzeData | null modulesData: ModulesData | null selectedSourceIndex: number | null moduleDepthMap: Map environmentFilter: 'client' | 'server' filterSource?: (sourceIndex: number) => boolean isLoading?: boolean } function formatBytes(bytes: number): string { if (bytes === 0) return '0 B' if (bytes < 1024) return `${bytes} B` if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB` if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB` return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB` } export function Sidebar({ sidebarWidth, analyzeData, modulesData, selectedSourceIndex, moduleDepthMap, environmentFilter, filterSource, isLoading = false, }: SidebarProps) { filterSource = filterSource ?? (() => true) if (isLoading || !analyzeData) { return (
) } return (
{selectedSourceIndex != null ? ( ) : null}
) } function SelectionDetails({ analyzeData, modulesData, selectedSourceIndex, filterSource, moduleDepthMap, environmentFilter, }: { analyzeData: AnalyzeData modulesData: ModulesData | null selectedSourceIndex: number moduleDepthMap: Map environmentFilter: 'client' | 'server' filterSource: (sourceIndex: number) => boolean }) { const specialModuleType = getSpecialModuleType( analyzeData, selectedSourceIndex ) const selectedSource = selectedSourceIndex != null ? analyzeData.source(selectedSourceIndex) : undefined const hasChildModules = selectedSourceIndex != null && analyzeData.sourceChildren(selectedSourceIndex).length > 0 const childModuleCount = hasChildModules && selectedSourceIndex != null ? analyzeData.getRecursiveModuleCount(selectedSourceIndex, filterSource) : null const { size, compressedSize } = analyzeData.getRecursiveSizes( selectedSourceIndex, filterSource ) const chunks = selectedSourceIndex != null ? analyzeData.sourceChunks(selectedSourceIndex) : [] return (

{selectedSource?.path || 'All Route Modules'}

{selectedSourceIndex != null && analyzeData.source(selectedSourceIndex) ? (
{formatBytes(compressedSize)} compressed (estimated) Estimated compressed size. Modules are compressed in isolation which may differ from their size in the final chunk.
{formatBytes(size)}{' '} uncompressed Uncompressed modules may still be minified, tree-shaken, and dead-code eliminated. They just don't account for general compression like gzip.
{hasChildModules && childModuleCount != null ? (
{childModuleCount} {childModuleCount === 1 ? 'module' : 'modules'}
) : null}
) : null}
{selectedSourceIndex != null && analyzeData.source(selectedSourceIndex) && (specialModuleType === SpecialModule.POLYFILL_MODULE || specialModuleType === SpecialModule.POLYFILL_NOMODULE) && (
Polyfill
Next.js built-in polyfills
)} {selectedSourceIndex != null && analyzeData.source(selectedSourceIndex) && !hasChildModules && ( <> {modulesData && ( )} {chunks.length > 0 ? (

Output Chunks

    {chunks.map((chunk) => (
  • {chunk}
  • ))}
) : null} )}
) } function InlineHelpTooltip({ children }: { children: React.ReactNode }) { return ( {children} ) }