Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function openInEditor() {
:chunk="chunk"
:session="session"
:show-modules="false"
:show-imports="false"
/>
</div>
</div>
Expand Down
33 changes: 25 additions & 8 deletions packages/devtools-vite/src/app/components/data/ChunkDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,51 @@ withDefaults(defineProps<{
chunk: ChunkInfo
session: SessionContext
showModules?: boolean
showImports?: boolean
}>(), {
showModules: true,
showImports: true,
})
</script>

<template>
<div flex="~ col gap-3">
<div flex="~ gap-4 items-center">
<div flex="~ gap-3 items-center">
<div flex="~ gap-2 items-center" :title="`Chunk #${chunk.chunk_id}`">
<div i-ph-shapes-duotone />
<div>{{ chunk.name || '[unnamed]' }}</div>
<DisplayBadge :text="chunk.reason" />
</div>

<div flex-auto />

<span op50 font-mono>#{{ chunk.chunk_id }}</span>
<div flex="~ gap-1 items-center">
<div i-carbon-document-import />
{{ chunk.imports.length }}
</div>
<div flex="~ gap-1 items-center">
<div i-ph-package-duotone />
{{ chunk.modules.length }}
</div>
</div>

<!-- TODO -->
<!-- <div op50>
Imports
</div>
<div flex="~ col gap-1" ws-nowrap>
{{ chunk.imports }}
</div> -->
<template v-if="showImports && chunk.imports.length > 0">
<div op50>
Imports
</div>
<div flex="~ col gap-1" ws-nowrap>
<DisplayChunkImports
v-for="(importChunk, index) in chunk.imports"
:key="index"
:chunk-import="importChunk"
:session="session"
:importer="chunk"
hover="bg-active"
border="~ base rounded" px2 py1 w-full
/>
</div>
</template>

<template v-if="showModules">
<div op50>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup lang="ts">
import type { SessionContext } from '../../../shared/types/data'
import { useRpc } from '#imports'
import { useAsyncState } from '@vueuse/core'

const props = defineProps<{
chunk: number
session: SessionContext
}>()

const emit = defineEmits<{
(e: 'close'): void
}>()

const rpc = useRpc()
const { state, isLoading } = useAsyncState(
async () => {
return await rpc.value!['vite:rolldown:get-chunk-info']?.({
session: props.session.id,
id: props.chunk,
})
},
null,
)
</script>

<template>
<VisualLoading v-if="isLoading" />

<div v-if="state" p4 pt-12 relative h-full w-full of-auto z-panel-content>
<DisplayCloseButton
absolute right-2 top-1.5
@click="emit('close')"
/>
<DataChunkDetails :session="session" :chunk="state" />
</div>
</template>
61 changes: 61 additions & 0 deletions packages/devtools-vite/src/app/components/display/ChunkImports.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<script lang="ts" setup>
import type { ChunkImport, Chunk as ChunkInfo } from '@rolldown/debug'
import type { SessionContext } from '../../../shared/types/data'
import { useRoute } from '#app/composables/router'
import { useAsyncState } from '@vueuse/core'
import { useRpc } from '../../../modules/rpc/runtime/composables/rpc'

const props = defineProps<{
chunkImport: ChunkImport
session: SessionContext
importer: ChunkInfo
}>()

const route = useRoute()

const rpc = useRpc()
const { state: chunk } = useAsyncState(
async () => {
return await rpc.value!['vite:rolldown:get-chunk-info']?.({
session: props.session.id,
id: props.chunkImport.chunk_id,
})
},
null,
)
</script>

<template>
<!-- <VisualLoading /> -->
<NuxtLink v-if="chunk" flex="~ items-center" :to="{ path: route.path, query: { chunk: chunk.chunk_id } }">
<!-- Icon, Name, Reason -->
<div flex="~ gap-2 items-center" :title="`Chunk #${chunk.chunk_id}`">
<div v-if="chunkImport.kind === 'import-statement'" i-ph-file-duotone />
<div v-if="chunkImport.kind === 'dynamic-import'" i-ph-lightning-duotone />
<div>{{ chunk.name || '[unnamed]' }}</div>
<DisplayBadge :text="chunk.reason" />

<!-- Import Kind -->
<DisplayBadge v-if="chunkImport.kind === 'import-statement'" text="statement" :color="210" />
<DisplayBadge v-if="chunkImport.kind === 'dynamic-import'" text="dynamic" :color="30" />
</div>

<div flex-auto />

<div text-sm flex="~ items-center gap-2">
<span op50 font-mono>#{{ chunk.chunk_id }}</span>
<div flex="~ gap-1 items-center">
<div i-carbon-document-import />
{{ chunk.imports.length }}
</div>
<div flex="~ gap-1 items-center">
<div i-ph-package-duotone />
{{ chunk.modules.length }}
</div>
</div>
</NuxtLink>
</template>

<style>

</style>
29 changes: 28 additions & 1 deletion packages/devtools-vite/src/app/pages/session/[session].vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,17 @@ function closePluginPanel() {
router.replace({ query: { ...route.query, plugin: undefined } })
}

function closeChunkPanel() {
router.replace({ query: { ...route.query, chunk: undefined } })
}

onKeyDown('Escape', (e) => {
e.preventDefault()

if (!e.isTrusted || e.repeat)
return

const { module, asset, plugin } = route.query
const { module, asset, plugin, chunk } = route.query

if (module)
closeFlowPanel()
Expand All @@ -51,6 +55,9 @@ onKeyDown('Escape', (e) => {

if (plugin)
closePluginPanel()

if (chunk)
closeChunkPanel()
})

useSideNav(() => {
Expand Down Expand Up @@ -168,5 +175,25 @@ onMounted(async () => {
/>
</div>
</div>

<!-- for chunks -->
<div
v-if="route.query.chunk" fixed inset-0
backdrop-blur-8 backdrop-brightness-95 z-panel-content
@click.self="closeChunkPanel"
>
<div
:key="(route.query.chunk as string)"
fixed right-0 bottom-0 top-20 z-panel-content
bg-glass border="l t base rounded-tl-xl"
class="left-20 xl:left-100 2xl:left-150"
>
<DataChunkDetailsLoader
:chunk="(Number(route.query.chunk))"
:session="session"
@close="closeChunkPanel"
/>
</div>
</div>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineRpcFunction } from '@vitejs/devtools-kit'
import { getLogsManager } from '../utils'

export const rolldownGetChunkInfo = defineRpcFunction({
name: 'vite:rolldown:get-chunk-info',
type: 'query',
setup: (context) => {
const manager = getLogsManager(context)
return {
handler: async ({ session, id }: { session: string, id: number }) => {
const reader = await manager.loadSession(session)
return reader.manager.chunks.get(id)
},
}
},
})
2 changes: 2 additions & 0 deletions packages/devtools-vite/src/node/rpc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { openInEditor } from './functions/open-in-editor'
import { openInFinder } from './functions/open-in-finder'
import { rolldownGetAssetDetails } from './functions/rolldown-get-asset-details'
import { rolldownGetAssetsList } from './functions/rolldown-get-assets-list'
import { rolldownGetChunkInfo } from './functions/rolldown-get-chunk-info'
import { rolldownGetChunksGraph } from './functions/rolldown-get-chunks-graph'
import { rolldownGetModuleInfo } from './functions/rolldown-get-module-info'
import { rolldownGetModuleRawEvents } from './functions/rolldown-get-module-raw-events'
Expand All @@ -27,6 +28,7 @@ export const rpcFunctions = [
rolldownGetAssetsList,
rolldownGetAssetDetails,
rolldownGetPluginDetails,
rolldownGetChunkInfo,
] as const

export type ServerFunctions = RpcDefinitionsToFunctions<typeof rpcFunctions>
Expand Down
Loading