Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/bundle-analyzer/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default function Home() {
size: number
server?: boolean
client?: boolean
traced?: boolean
} | null>(null)
const [searchQuery, setSearchQuery] = useState('')

Expand Down Expand Up @@ -265,6 +266,9 @@ export default function Home() {
{hoveredNodeInfo.server && (
<Badge variant="server">server</Badge>
)}
{hoveredNodeInfo.traced && (
<Badge variant="traced">traced</Badge>
)}
</span>
)}
</>
Expand Down
62 changes: 48 additions & 14 deletions apps/bundle-analyzer/components/import-chain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Server,
Globe,
MessageCircleQuestion,
Package,
} from 'lucide-react'
import { useMemo, useState } from 'react'
import type {
Expand Down Expand Up @@ -52,6 +53,7 @@ interface DependentInfo {
sourceIndex: number | undefined
ident: string
isAsync: boolean
isTraced: boolean
depth: number
}

Expand Down Expand Up @@ -219,13 +221,23 @@ export function ImportChain({
.map((index: number) => ({
index,
async: false,
traced: false,
depth: depthMap.get(index) ?? Infinity,
})),
...modulesData
.asyncModuleDependents(currentModuleIndex)
.map((index: number) => ({
index,
async: true,
traced: false,
depth: depthMap.get(index) ?? Infinity,
})),
...modulesData
.tracedModuleDependents(currentModuleIndex)
.map((index: number) => ({
index,
async: false,
traced: true,
depth: depthMap.get(index) ?? Infinity,
})),
]
Expand All @@ -243,14 +255,15 @@ export function ImportChain({

// Build info for each dependent
const dependentsInfo: DependentInfo[] = validDependents.map(
({ index: moduleIndex, async: isAsync, depth }) => {
({ index: moduleIndex, async: isAsync, traced: isTraced, depth }) => {
const sourceIndex = getSourceIndexFromModuleIndex(moduleIndex)
let ident = modulesData.module(moduleIndex)?.ident || ''
return {
moduleIndex,
sourceIndex,
ident,
isAsync,
isTraced,
depth,
}
}
Expand Down Expand Up @@ -376,6 +389,11 @@ export function ImportChain({
(async)
</span>
)}
{currentItemInfo?.isTraced && (
<span className="text-xs text-muted-foreground italic">
(traced)
</span>
)}
{index > 0 ? (
<ArrowUp className="w-4 h-4 text-muted-foreground" />
) : undefined}
Expand Down Expand Up @@ -406,19 +424,7 @@ export function ImportChain({
{currentItemInfo?.isAsync && <div className="h-8" />}
<div className="flex items-center gap-2">
<div className="flex flex-col gap-1 items-center">
{!level.layer ? (
<div title="Unknown">
<MessageCircleQuestion className="w-3 h-3 text-gray-500" />
</div>
) : /app/.test(level.layer || '') ? (
<div title="App Router">
<Box className="w-3 h-3 text-green-500" />
</div>
) : (
<div title="Pages Router">
<File className="w-3 h-3 text-purple-500" />
</div>
)}
<LayerIcon layer={level.layer} />
</div>

<div className="flex-1 border border-border rounded px-2 py-1 bg-background">
Expand Down Expand Up @@ -536,3 +542,31 @@ export function ImportChain({
</div>
)
}

function LayerIcon({ layer }: { layer: string | undefined }) {
if (!layer || layer === 'external') {
return (
<div title="Unknown">
<MessageCircleQuestion className="w-3 h-3 text-gray-500" />
</div>
)
} else if (layer.includes('app')) {
return (
<div title={`App Router (${layer})`}>
<Box className="w-3 h-3 text-green-500" />
</div>
)
} else if (layer === 'externals-tracing') {
return (
<div title="External Asset">
<Package className="w-3 h-3" />
</div>
)
} else {
return (
<div title={`Pages Router (${layer})`}>
<File className="w-3 h-3 text-purple-500" />
</div>
)
}
}
1 change: 1 addition & 0 deletions apps/bundle-analyzer/components/treemap-visualizer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@ export function TreemapVisualizer({
size: node.size,
server: node.server,
client: node.client,
traced: node.traced,
}

if (node.type === 'directory') {
Expand Down
2 changes: 2 additions & 0 deletions apps/bundle-analyzer/components/ui/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const badgeVariants = cva(
'border-transparent bg-blue-50 dark:bg-blue-950 text-blue-700 dark:text-blue-300 ring-1 ring-inset ring-blue-700/10 dark:ring-blue-300/20',
server:
'border-transparent bg-purple-50 dark:bg-purple-950 text-purple-700 dark:text-purple-300 ring-1 ring-inset ring-purple-700/10 dark:ring-purple-300/20',
traced:
'border-transparent bg-grey-50 dark:bg-grey-950 text-grey-700 dark:text-grey-300 ring-1 ring-inset ring-grey-700/10 dark:ring-grey-300/20',
polyfill:
'border-transparent bg-polyfill/10 dark:bg-polyfill/30 text-polyfill dark:text-polyfill-foreground ring-1 ring-inset ring-polyfill/20',
},
Expand Down
23 changes: 22 additions & 1 deletion apps/bundle-analyzer/lib/analyze-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ interface ModulesDataHeader {
modules: AnalyzeModule[]
module_dependents: EdgesDataReference
async_module_dependents: EdgesDataReference
traced_module_dependents: EdgesDataReference
module_dependencies: EdgesDataReference
async_module_dependencies: EdgesDataReference
traced_module_dependencies: EdgesDataReference
}

/**
Expand Down Expand Up @@ -167,6 +169,13 @@ export class ModulesData {
)
}

tracedModuleDependents(index: ModuleIndex): ModuleIndex[] {
return this.readEdgesDataAtIndex(
this.modulesHeader.traced_module_dependents,
index
)
}

moduleDependencies(index: ModuleIndex): ModuleIndex[] {
return this.readEdgesDataAtIndex(
this.modulesHeader.module_dependencies,
Expand All @@ -181,6 +190,13 @@ export class ModulesData {
)
}

tracedModuleDependencies(index: ModuleIndex): ModuleIndex[] {
return this.readEdgesDataAtIndex(
this.modulesHeader.traced_module_dependencies,
index
)
}

getRawModulesHeader(): ModulesDataHeader {
return this.modulesHeader
}
Expand Down Expand Up @@ -447,10 +463,15 @@ export class AnalyzeData {
client = true
} else if (outputFile.filename.startsWith('[project]/')) {
traced = true
server = true
} else {
server = true
}
if (outputFile.filename.endsWith('.js')) {
if (
outputFile.filename.endsWith('.js') ||
outputFile.filename.endsWith('.mjs') ||
outputFile.filename.endsWith('.cjs')
) {
js = true
} else if (outputFile.filename.endsWith('.css')) {
css = true
Expand Down
8 changes: 8 additions & 0 deletions apps/bundle-analyzer/lib/module-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ export function computeModuleDepthMap(
}
}

// Process traced dependencies
const tracedDependencies = modulesData.tracedModuleDependencies(moduleIndex)
for (const depIndex of tracedDependencies) {
if (!depthMap.has(depIndex)) {
depthMap.set(depIndex, newDepth)
}
}

i++

// Check if we need to process the next delayed queue to insert its items into the depth map
Expand Down
6 changes: 1 addition & 5 deletions apps/bundle-analyzer/lib/treemap-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface LayoutNodeInfo {
size: number
server?: boolean
client?: boolean
traced?: boolean
}

export interface LayoutNode extends LayoutNodeInfo {
Expand All @@ -25,7 +26,6 @@ export interface LayoutNode extends LayoutNodeInfo {
titleBarHeight?: number
children?: LayoutNode[]
itemCount?: number
traced?: boolean
js?: boolean
css?: boolean
json?: boolean
Expand Down Expand Up @@ -112,7 +112,6 @@ function computeTreemapLayoutFromAnalyzeInternal(
foldedPath: string,
rect: LayoutRect,
metadata: SourceMetadata[],
filterSource: ((sourceIndex: SourceIndex) => boolean) | undefined,
sizeMode: SizeMode
): LayoutNode {
const source = analyzeData.source(sourceIndex)
Expand All @@ -139,7 +138,6 @@ function computeTreemapLayoutFromAnalyzeInternal(
foldedPath + source.path,
rect,
metadata,
filterSource,
sizeMode
)
}
Expand Down Expand Up @@ -253,7 +251,6 @@ function computeTreemapLayoutFromAnalyzeInternal(
'',
childRects[i],
metadata,
filterSource,
sizeMode
)
)
Expand Down Expand Up @@ -288,7 +285,6 @@ export function computeTreemapLayoutFromAnalyze(
'',
rect,
metadata,
filterSource,
sizeMode
)
}
11 changes: 11 additions & 0 deletions apps/bundle-analyzer/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
const developmentRewrites = () => {
return [
{
source: '/data/:path*',
destination: 'http://localhost:4000/data/:path*',
},
]
}

/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
distDir: 'dist',
rewrites:
process.env.NODE_ENV === 'development' ? developmentRewrites : undefined,
}

export default nextConfig
Loading
Loading