Skip to content
Open
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
41 changes: 0 additions & 41 deletions packages/rolldown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
},
"dependencies": {
"@floating-ui/dom": "catalog:frontend",
"@pnpm/read-project-manifest": "catalog:deps",
"@rolldown/debug": "catalog:deps",
"@vitejs/devtools-kit": "workspace:*",
"birpc": "catalog:deps",
Comment thread
webfansplz marked this conversation as resolved.
Expand Down Expand Up @@ -78,45 +77,5 @@
"tsdown": "catalog:build",
"unocss": "catalog:build",
"vite-hot-client": "catalog:frontend"
},
"inlinedDependencies": {
"@babel/code-frame": "7.29.0",
"@babel/helper-validator-identifier": "7.28.5",
"@gwhitney/detect-indent": "7.0.1",
"@pnpm/constants": "1001.3.1",
"@pnpm/core-loggers": "1001.0.9",
"@pnpm/error": "1000.1.0",
"@pnpm/graceful-fs": "1000.1.0",
"@pnpm/logger": "1001.0.1",
"@pnpm/manifest-utils": "1002.0.5",
"@pnpm/read-project-manifest": "1001.2.6",
"@pnpm/semver.peer-range": "1000.0.0",
"@pnpm/text.comments-parser": "1000.0.0",
"@pnpm/types": "1001.3.0",
"@pnpm/write-project-manifest": "1000.0.16",
"bole": "5.0.25",
"error-ex": "1.3.4",
"fast-deep-equal": "3.1.3",
"fast-safe-stringify": "2.1.1",
"graceful-fs": "4.2.11",
"imurmurhash": "0.1.4",
"individual": "3.0.0",
"is-arrayish": "0.2.1",
"is-windows": "1.0.2",
"js-tokens": "4.0.0",
"js-yaml": "4.1.1",
"json-parse-even-better-errors": "2.3.1",
"json5": "2.2.3",
"lines-and-columns": "1.2.4",
"parse-json": "5.2.0",
"picocolors": "1.1.1",
"read-yaml-file": "2.1.0",
"semver": "7.8.0",
"signal-exit": "4.1.0",
"split2": "4.2.0",
"strip-bom": "4.0.0",
"strip-comments-strings": "1.2.0",
"write-file-atomic": "5.0.1",
"write-yaml-file": "5.0.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ const props = defineProps<{
const emit = defineEmits<{
(e: 'close'): void
}>()
const parsedPackage = computed(() => {
const match = props.package.match(/^(@?[^@]+)@(.+)$/)
const [, name, version] = match!
return { name, version }
})
const rpc = useRpc()
const { state, isLoading } = useAsyncState(
async () => {
Expand All @@ -33,6 +28,7 @@ const { state, isLoading } = useAsyncState(
)

const normalizedBundledFiles = computed(() => state.value?.files?.filter(f => !!f.transformedCodeSize) ?? [])
const packageName = computed(() => state.value?.name ?? props.package)

const importers = computed(() => {
const pathMap = new Map()
Expand All @@ -43,7 +39,7 @@ const importers = computed(() => {
})

function openInNpm() {
const url = `https://www.npmjs.com/package/${parsedPackage.value.name}`
const url = `https://www.npmjs.com/package/${packageName.value}`
window.open(url, '_blank')
}
</script>
Expand All @@ -56,7 +52,7 @@ function openInNpm() {
<div flex="~ gap-3 items-center" :title="package">
<div flex="~ items-center gap-1">
<div>
<DisplayHighlightedPackageName :name="parsedPackage.name!" />
<DisplayHighlightedPackageName :name="packageName" />
</div>
<DisplayFileSizeBadge :bytes="state.transformedCodeSize" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const groupedDuplicatePackages = computed(() =>
<template>
<div v-if="duplicatePackages.length" min-w-max flex="~ col gap-3">
<div v-for="(p, i) of groupedDuplicatePackages" :key="i">
<PackagesTable :packages="p" :session="session" group-view disable-size-sort />
<PackagesTable :packages="p" :session="session" group-view disable-size-sort show-used-badge />
</div>
</div>
<template v-else>
Expand Down
20 changes: 15 additions & 5 deletions packages/rolldown/src/app/components/packages/Table.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import type { PackageInfo, SessionContext } from '~~/shared/types'
import DataVirtualList from '@vitejs/devtools-ui/components/DataVirtualList.vue'
import DisplayBadge from '@vitejs/devtools-ui/components/DisplayBadge.vue'
import { useCycleList } from '@vueuse/core'
import { Tooltip, Menu as VMenu } from 'floating-vue'
import { settings } from '~~/app/state/settings'
Expand All @@ -14,12 +15,14 @@ withDefaults(defineProps<{
itemSize?: number
pageMode?: boolean
scroller?: 'dynamic' | 'fixed' | 'window'
showUsedBadge?: boolean
}>(), {
disableSizeSort: false,
groupView: false,
itemSize: 36,
pageMode: false,
scroller: 'fixed',
showUsedBadge: false,
})

const route = useRoute()
Expand All @@ -40,7 +43,7 @@ function toggleSizeSortType() {
role="table"
min-w-max h-full min-h-0 border="~ base rounded-xl"
:items="packages"
key-prop="dir"
key-prop="id"
:item-size="itemSize"
:page-mode="pageMode"
:scroller="scroller"
Expand Down Expand Up @@ -81,7 +84,7 @@ function toggleSizeSortType() {
h-9
class="border-base border-b-1 border-dashed"
:class="[index === packages.length - 1 ? 'border-b-0' : '']"
:to="{ path: route.path, query: { package: `${item.name}@${item.version}` } }"
:to="{ path: route.path, query: { package: item.id } }"
>
<Tooltip
:triggers="['hover']"
Expand All @@ -100,11 +103,17 @@ function toggleSizeSortType() {
</span>
</template>
</Tooltip>
<div role="cell" flex="~ items-center" text-left flex-none font-mono py1.5 px2 text-sm min-w40 op80 :class="{ 'text-primary': item.duplicated }">
{{ item.version }}
<div role="cell" flex="~ items-center gap-1" text-left flex-none font-mono py1.5 px2 text-sm min-w40 op80 :class="{ 'text-primary': item.duplicated }">
<span>{{ item.version }}</span>
<DisplayBadge
v-if="showUsedBadge && item.isUsed === false"
text="Unbundled"
:color="30"
as="span"
/>
</div>
<div role="cell" flex="~ items-center justify-end" flex-none font-mono py1.5 px2 text-sm min-w40 op80>
<VMenu :delay="{ show: 200, hide: 0 }">
<VMenu v-if="item.transformedCodeSize > 0" :delay="{ show: 200, hide: 0 }">
<DisplayFileSizeBadge :bytes="item.transformedCodeSize" />
<template #popper>
<div p2 flex="~ col gap-1">
Expand All @@ -117,6 +126,7 @@ function toggleSizeSortType() {
</div>
</template>
</VMenu>
<span v-else op50 ws-nowrap>-</span>
</div>
<div role="cell" flex="~ items-center" flex-1 font-mono py1.5 pl20 pr2 text-sm op80>
<PackagesImporters :package="item" :session="session" :show-version="groupView" />
Expand Down
3 changes: 2 additions & 1 deletion packages/rolldown/src/app/pages/compare/[sessions]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const sessions = ref<SessionCompareContext[]>([])
const packages = ref<{ total: number, duplicated: number }[]>([])

async function getPackages(id: string) {
const packages = await rpc.value.call('vite:rolldown:get-packages', { session: id })
const packageMeta = await rpc.value.call('vite:rolldown:get-packages', { session: id })
const packages = packageMeta.packages
const duplicatedPackages = packages.filter(p => p.duplicated)
return {
total: packages.length,
Expand Down
73 changes: 49 additions & 24 deletions packages/rolldown/src/app/pages/session/[session]/packages.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import type { PackageInfo, SessionContext } from '~~/shared/types/data'
import type { PackageInfo, PackageMeta, SessionContext } from '~~/shared/types/data'
import type { ClientSettings } from '~/state/settings'
import type { PackageChartInfo, PackageChartNode } from '~/types/chart'
import { computedWithControl, useAsyncState, useMouse } from '@vueuse/core'
Expand Down Expand Up @@ -33,13 +33,19 @@ const packageTypeRules = [
description: 'Transitive Dependencies',
icon: 'i-octicon:package-24 light:filter-invert-30!',
},
{
match: /.*/,
name: 'unbundled',
description: 'Unbundled Dependencies',
icon: 'i-ph-package-duotone',
},
]
const rpc = useRpc()
const searchValue = ref<{ search: string, selected: string[] }>({
const searchValue = ref<{ search: string, selected: string[] | null }>({
search: '',
selected: ['direct', 'transitive'],
})
const { state: packages, isLoading } = useAsyncState(
const { state: packageMeta, isLoading } = useAsyncState<PackageMeta | null>(
async () => {
return await rpc.value.call(
'vite:rolldown:get-packages',
Expand All @@ -48,26 +54,43 @@ const { state: packages, isLoading } = useAsyncState(
},
null,
)
const isSupported = computed(() => packageMeta.value?.isSupported ?? true)
const packages = computed(() => packageMeta.value?.packages ?? [])

const fuse = computedWithControl(
() => packages.value,
() => new Fuse(packages.value!, {
() => new Fuse(packages.value, {
includeScore: true,
keys: ['name'],
ignoreLocation: true,
threshold: 0.4,
}),
)

const duplicatePackagesCount = computed(() => {
if (!packages.value) {
return 0
}
return Object.values(packages.value!.reduce((acc, p) => {
acc[p.name] = (acc[p.name] || 0) + 1
return acc
}, {} as Record<string, number>)).filter(count => count > 1).length
})
const searched = computed(() => (
searchValue.value.search
? fuse.value.search(searchValue.value.search).map(r => r.item)
: [...packages.value]),
)

function matchesSelectedPackageType(item: PackageInfo) {
const selected = searchValue.value.selected
if (!selected)
return true

if (item.isUsed === false)
return selected.includes('unbundled')

return selected.includes(item.type || '')
}

const filteredPackages = computed(() => searched.value.filter(matchesSelectedPackageType))

const duplicatePackagesCount = computed(() => new Set(
packages.value
.filter(item => item.duplicated)
.map(item => item.name),
).size)

const packageViewTypes = computed(() => [
{
Expand All @@ -87,21 +110,15 @@ const packageViewTypes = computed(() => [
},
] as const)

const searched = computed(() => (
searchValue.value.search
? fuse.value.search(searchValue.value.search).map(r => r.item)
: [...(packages.value || [])]),
)

const normalizedPackages = computed(() => {
const packagesSizeSortType = settings.value.packageSizeSortType
const data = searched.value.toSorted((a, b) => (a.name || '').localeCompare(b.name || ''))
const data = filteredPackages.value.toSorted((a, b) => (a.name || '').localeCompare(b.name || ''))

const sortedPackages = packagesSizeSortType
? data.sort((a, b) => packagesSizeSortType === 'asc' ? a.transformedCodeSize - b.transformedCodeSize : b.transformedCodeSize - a.transformedCodeSize)
: data

return sortedPackages.filter(item => !searchValue.value.selected || searchValue.value.selected.some(rule => rule.match(item.type!)))
return sortedPackages
})

function toggleDisplay(type: ClientSettings['packageViewType']) {
Expand All @@ -123,7 +140,7 @@ const { tree, chartOptions, graph, nodeHover, nodeSelected, selectedNode, select
},
onClick(node) {
if (node.meta?.type === 'package') {
router.replace({ query: { ...route.query, package: `${node.meta?.name}@${node.meta?.version}` } })
router.replace({ query: { ...route.query, package: node.meta.id } })
}
},
onLeave() {
Expand Down Expand Up @@ -151,6 +168,14 @@ watch(() => settings.value.packageViewType, () => {

<template>
<VisualLoading v-if="isLoading" />
<div v-else-if="!isSupported" h-full flex="~ col gap-2 items-center justify-center" p4 text-center>
<p m0 op50>
Package graph is not available for this build
</p>
<p m0 op40 text-sm>
Rebuild with Rolldown 1.0.2 or later to generate it.
</p>
</div>
<div v-else relative h-full min-h-0 flex="~ col">
<div sticky left-4 right-4 top-4 z-panel-nav p-4>
<DataSearchPanel v-model="searchValue" :rules="packageTypeRules">
Expand Down Expand Up @@ -179,7 +204,7 @@ watch(() => settings.value.packageViewType, () => {
<div
fixed bottom-4 py-1 px-2 bg-glass left="1/2" translate-x="-1/2" border="~ base rounded-full" text="center xs"
>
<span op50>{{ searched.length }} of {{ packages?.length || 0 }}</span>
<span op50>{{ normalizedPackages.length }} of {{ packages.length }}</span>
</div>
</template>
<template v-else-if="settings.packageViewType === 'treemap'">
Expand All @@ -203,7 +228,7 @@ watch(() => settings.value.packageViewType, () => {
</span>
</template>
<template v-else-if="settings.packageViewType === 'duplicate-packages'">
<PackagesDuplicated :packages="normalizedPackages" :session="session" />
<PackagesDuplicated :packages="packages" :session="session" />
</template>
</div>
<DisplayGraphHoverView :hover-x="mouse.x" :hover-y="mouse.y">
Expand Down
18 changes: 17 additions & 1 deletion packages/rolldown/src/node/rolldown/events-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Event, HookLoadCallEnd, HookLoadCallStart, HookResolveIdCallEnd, HookResolveIdCallStart, HookTransformCallEnd, HookTransformCallStart, Module as ModuleInfo } from '@rolldown/debug'
import type { Event, HookLoadCallEnd, HookLoadCallStart, HookResolveIdCallEnd, HookResolveIdCallStart, HookTransformCallEnd, HookTransformCallStart, Module as ModuleInfo, PackageInfo as RolldownPackageInfo } from '@rolldown/debug'
import type { ModuleBuildMetrics, PluginBuildMetrics, RolldownAssetInfo, RolldownChunkInfo } from '../../shared/types'
import { guessChunkName } from '../../shared/utils/guess-chunk-name'
import { getInitialChunkIds } from '../utils/chunk'
Expand Down Expand Up @@ -42,6 +42,8 @@ export interface RolldownEventsManagerSnapshot {
lastEvent: RolldownEvent | undefined
chunks: Array<[number, RolldownChunkInfo]>
modules: Array<[string, ModuleSnapshot]>
packageGraphReady: boolean
packages: Array<[string, RolldownPackageInfo]>
source_refs: Array<[string, ContentInfo]>
module_build_hook_events: Array<[string, PendingModuleBuildHookEvent]>
module_build_metrics: Array<[string, ModuleBuildMetrics]>
Expand Down Expand Up @@ -98,6 +100,8 @@ export class RolldownEventsManager {
assets: Map<string, RolldownAssetInfo> = new Map()
chunkAssetMap = new Map<number, RolldownAssetInfo>()
modules: Map<string, ModuleInfo & { build_metrics?: ModuleBuildMetrics }> = new Map()
packageGraphReady = false
packages: Map<string, RolldownPackageInfo> = new Map()
source_refs: Map<string, ContentInfo> = new Map()
module_build_hook_events: Map<string, PendingModuleBuildHookEvent> = new Map()
module_build_metrics: Map<string, ModuleBuildMetrics> = new Map()
Expand Down Expand Up @@ -256,6 +260,12 @@ export class RolldownEventsManager {
return
}

if (event.action === 'PackageGraphReady') {
this.packageGraphReady = true
this.packages = new Map(event.packages.map(pkg => [pkg.package_id, pkg]))
return
}

this.recordBuildMetrics(event as ModuleBuildHookEvents)

if ('module_id' in event) {
Expand Down Expand Up @@ -304,6 +314,8 @@ export class RolldownEventsManager {
this.assets.clear()
this.chunkAssetMap.clear()
this.modules.clear()
this.packageGraphReady = false
this.packages.clear()
this.source_refs.clear()
this.module_build_hook_events.clear()
this.module_build_metrics.clear()
Expand All @@ -317,6 +329,8 @@ export class RolldownEventsManager {
eventCount: this.eventCount,
lastEvent: this.lastEvent,
chunks: Array.from(this.chunks.entries()),
packageGraphReady: this.packageGraphReady,
packages: Array.from(this.packages.entries()),
modules: Array.from(this.modules.entries()).map(([id, module]) => {
const { build_metrics, ...snapshot } = module
return [id, snapshot]
Expand All @@ -334,6 +348,8 @@ export class RolldownEventsManager {
this.eventCount = snapshot.eventCount
this.lastEvent = snapshot.lastEvent
this.chunks = new Map(snapshot.chunks)
this.packageGraphReady = snapshot.packageGraphReady ?? !!snapshot.packages?.length
this.packages = new Map(snapshot.packages ?? [])
this.assets.clear()
this.chunkAssetMap.clear()
this.source_refs = new Map(snapshot.source_refs)
Expand Down
Loading
Loading