From 4e1e3a0b15f7729874d82b08e9c0f89e63e1f9b8 Mon Sep 17 00:00:00 2001 From: Alexander Karan <47707063+AlexanderKaran@users.noreply.github.com> Date: Wed, 15 Jul 2026 07:39:57 +0800 Subject: [PATCH] Added All Deps --- .../src/components/DependencyStatsTable.astro | 4 +- packages/docs/src/content.config.ts | 1 + .../src/content/devtime/starter-astro.json | 3 +- .../src/content/devtime/starter-mastro.json | 3 +- .../src/content/devtime/starter-next-js.json | 1 + .../src/content/devtime/starter-nuxt.json | 1 + .../content/devtime/starter-react-router.json | 1 + .../content/devtime/starter-solid-start.json | 3 +- .../content/devtime/starter-sveltekit.json | 1 + .../devtime/starter-tanstack-start-react.json | 1 + packages/docs/src/content/docs/methodology.md | 3 ++ packages/docs/src/lib/collections.ts | 5 ++ .../docs/src/pages/framework/[slug].astro | 8 ++-- packages/starter-astro/ci-stats.json | 1 + packages/starter-astro/stats/5.16.15.json | 1 + packages/starter-mastro/ci-stats.json | 1 + packages/starter-next-js/ci-stats.json | 1 + packages/starter-next-js/stats/16.1.1.json | 1 + packages/starter-nuxt/ci-stats.json | 1 + packages/starter-nuxt/stats/4.2.2.json | 1 + packages/starter-react-router/ci-stats.json | 1 + .../starter-react-router/stats/7.10.1.json | 1 + packages/starter-solid-start/ci-stats.json | 1 + packages/starter-solid-start/stats/1.2.1.json | 1 + packages/starter-sveltekit/ci-stats.json | 1 + packages/starter-sveltekit/stats/2.49.4.json | 1 + .../ci-stats.json | 1 + .../stats/1.145.3.json | 1 + packages/stats-generator/src/collect-stats.ts | 20 +++----- packages/stats-generator/src/save-ci-stats.ts | 17 +++++-- packages/stats-generator/src/types.ts | 1 + packages/stats-generator/src/utils.ts | 47 ++++++++++++++++++- 32 files changed, 108 insertions(+), 27 deletions(-) diff --git a/packages/docs/src/components/DependencyStatsTable.astro b/packages/docs/src/components/DependencyStatsTable.astro index f60221d4..75d0d36e 100644 --- a/packages/docs/src/components/DependencyStatsTable.astro +++ b/packages/docs/src/components/DependencyStatsTable.astro @@ -11,8 +11,8 @@ const depsColumns = [ href: (row: Record) => `/framework/${getFrameworkSlug(row.package as string)}`, }, - { key: 'prodDependencies', header: 'Prod Deps' }, - { key: 'devDependencies', header: 'Dev Deps' }, + { key: 'directDependencies', header: 'Deps Dev / Prod' }, + { key: 'allDependencies', header: 'All Deps' }, { key: 'duplicateDependencies', header: 'Dup. Deps' }, { key: 'nodeModulesSize', header: 'node_modules' }, { key: 'nodeModulesSizeProdOnly', header: 'node_modules (prod)' }, diff --git a/packages/docs/src/content.config.ts b/packages/docs/src/content.config.ts index 32dc4c56..2561d396 100644 --- a/packages/docs/src/content.config.ts +++ b/packages/docs/src/content.config.ts @@ -20,6 +20,7 @@ const devtimeCollection = defineCollection({ order: z.number(), prodDependencies: z.number(), devDependencies: z.number(), + allDependencies: z.number(), installTime: timeSchema, coldBuildTime: timeSchema, warmBuildTime: timeSchema, diff --git a/packages/docs/src/content/devtime/starter-astro.json b/packages/docs/src/content/devtime/starter-astro.json index 9298e3a7..513ce124 100644 --- a/packages/docs/src/content/devtime/starter-astro.json +++ b/packages/docs/src/content/devtime/starter-astro.json @@ -5,7 +5,8 @@ "type": "starter-kit", "prodDependencies": 1, "devDependencies": 2, - "timingMeasuredAt": "2026-07-14T22:25:50.706Z", + "allDependencies": 0, + "timingMeasuredAt": "2026-07-14T07:44:26.499Z", "runner": "ubuntu-latest", "installTimeMs": 3160, "coldBuildTimeMs": 2595, diff --git a/packages/docs/src/content/devtime/starter-mastro.json b/packages/docs/src/content/devtime/starter-mastro.json index 1d9a23e2..350e2f50 100644 --- a/packages/docs/src/content/devtime/starter-mastro.json +++ b/packages/docs/src/content/devtime/starter-mastro.json @@ -5,7 +5,8 @@ "type": "starter-kit", "prodDependencies": 2, "devDependencies": 2, - "timingMeasuredAt": "2026-07-14T22:25:50.706Z", + "allDependencies": 0, + "timingMeasuredAt": "2026-07-14T07:44:26.499Z", "runner": "ubuntu-latest", "frameworkVersion": "unknown", "installTime": { diff --git a/packages/docs/src/content/devtime/starter-next-js.json b/packages/docs/src/content/devtime/starter-next-js.json index 656234ad..435dde77 100644 --- a/packages/docs/src/content/devtime/starter-next-js.json +++ b/packages/docs/src/content/devtime/starter-next-js.json @@ -3,6 +3,7 @@ "type": "starter-kit", "prodDependencies": 3, "devDependencies": 6, + "allDependencies": 0, "package": "starter-next-js", "isFocused": true, "installTimeMs": 7166, diff --git a/packages/docs/src/content/devtime/starter-nuxt.json b/packages/docs/src/content/devtime/starter-nuxt.json index fa04b6ca..3475694f 100644 --- a/packages/docs/src/content/devtime/starter-nuxt.json +++ b/packages/docs/src/content/devtime/starter-nuxt.json @@ -3,6 +3,7 @@ "type": "starter-kit", "prodDependencies": 3, "devDependencies": 2, + "allDependencies": 0, "package": "starter-nuxt", "isFocused": true, "installTimeMs": 7579, diff --git a/packages/docs/src/content/devtime/starter-react-router.json b/packages/docs/src/content/devtime/starter-react-router.json index 904aca6b..a269069f 100644 --- a/packages/docs/src/content/devtime/starter-react-router.json +++ b/packages/docs/src/content/devtime/starter-react-router.json @@ -3,6 +3,7 @@ "type": "starter-kit", "prodDependencies": 6, "devDependencies": 8, + "allDependencies": 0, "package": "starter-react-router", "isFocused": true, "installTimeMs": 2687, diff --git a/packages/docs/src/content/devtime/starter-solid-start.json b/packages/docs/src/content/devtime/starter-solid-start.json index 28f6c88b..d13b03bd 100644 --- a/packages/docs/src/content/devtime/starter-solid-start.json +++ b/packages/docs/src/content/devtime/starter-solid-start.json @@ -5,7 +5,8 @@ "type": "starter-kit", "prodDependencies": 5, "devDependencies": 0, - "timingMeasuredAt": "2026-07-14T22:25:50.706Z", + "allDependencies": 0, + "timingMeasuredAt": "2026-07-14T07:44:26.499Z", "runner": "ubuntu-latest", "installTimeMs": 3935, "nodeModulesSize": 168325120, diff --git a/packages/docs/src/content/devtime/starter-sveltekit.json b/packages/docs/src/content/devtime/starter-sveltekit.json index 1f98b14f..dc07d899 100644 --- a/packages/docs/src/content/devtime/starter-sveltekit.json +++ b/packages/docs/src/content/devtime/starter-sveltekit.json @@ -3,6 +3,7 @@ "type": "starter-kit", "prodDependencies": 0, "devDependencies": 7, + "allDependencies": 0, "package": "starter-sveltekit", "isFocused": true, "installTimeMs": 2878, diff --git a/packages/docs/src/content/devtime/starter-tanstack-start-react.json b/packages/docs/src/content/devtime/starter-tanstack-start-react.json index fb99d683..d0834759 100644 --- a/packages/docs/src/content/devtime/starter-tanstack-start-react.json +++ b/packages/docs/src/content/devtime/starter-tanstack-start-react.json @@ -3,6 +3,7 @@ "type": "starter-kit", "prodDependencies": 13, "devDependencies": 11, + "allDependencies": 0, "package": "starter-tanstack-start-react", "isFocused": true, "installTimeMs": 4572, diff --git a/packages/docs/src/content/docs/methodology.md b/packages/docs/src/content/docs/methodology.md index 6bd839f3..65e2bc30 100644 --- a/packages/docs/src/content/docs/methodology.md +++ b/packages/docs/src/content/docs/methodology.md @@ -87,6 +87,9 @@ of a typical new project. - Duplicate dependency details come from e18e dependency analysis messages collected for each starter package. +- All dependency counts come from the starter package's `pnpm-lock.yaml` + `packages` entries, which include direct and transitive resolved package + instances. - A duplicate dependency means multiple installed versions of the same package were found in the starter's dependency tree. - Framework detail pages show the package name, installed versions, and the diff --git a/packages/docs/src/lib/collections.ts b/packages/docs/src/lib/collections.ts index bb78dbfa..676fa743 100644 --- a/packages/docs/src/lib/collections.ts +++ b/packages/docs/src/lib/collections.ts @@ -136,8 +136,13 @@ export const depsStats = starterStats.map((f) => ({ name: f.name, package: f.package, isFocused: f.isFocused, + directDependencies: [ + f.devDependencies.toLocaleString(), + f.prodDependencies.toLocaleString(), + ].join(' / '), prodDependencies: f.prodDependencies, devDependencies: f.devDependencies, + allDependencies: f.allDependencies.toLocaleString(), duplicateDependencies: f.duplicateDependencies, nodeModulesSize: formatBytesToMB(f.nodeModulesSize), nodeModulesSizeProdOnly: formatBytesToMB(f.nodeModulesSizeProdOnly), diff --git a/packages/docs/src/pages/framework/[slug].astro b/packages/docs/src/pages/framework/[slug].astro index 89bee005..0008db44 100644 --- a/packages/docs/src/pages/framework/[slug].astro +++ b/packages/docs/src/pages/framework/[slug].astro @@ -75,8 +75,8 @@ const depsEntry = depsStats.find((e) => e.package === devtime.package)! const buildEntry = buildInstallData.find((e) => e.package === devtime.package)! const depsColumns = [ - { key: 'prodDependencies', header: 'Prod Deps' }, - { key: 'devDependencies', header: 'Dev Deps' }, + { key: 'directDependencies', header: 'Deps Dev / Prod' }, + { key: 'allDependencies', header: 'All Deps' }, ...(devtime.duplicateDependencies != null ? [{ key: 'duplicateDependencies', header: 'Dup. Deps' }] : []), @@ -92,8 +92,8 @@ const depsColumns = [ const depsData = [ { - prodDependencies: String(depsEntry.prodDependencies), - devDependencies: String(depsEntry.devDependencies), + directDependencies: depsEntry.directDependencies, + allDependencies: depsEntry.allDependencies, ...(devtime.duplicateDependencies != null ? { duplicateDependencies: String(devtime.duplicateDependencies) } : {}), diff --git a/packages/starter-astro/ci-stats.json b/packages/starter-astro/ci-stats.json index f8160914..e2b2188c 100644 --- a/packages/starter-astro/ci-stats.json +++ b/packages/starter-astro/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 1, "devDependencies": 2, + "allDependencies": 0, "duplicateDependencies": 17, "depInstallSize": 171119612, "e18eMessages": [ diff --git a/packages/starter-astro/stats/5.16.15.json b/packages/starter-astro/stats/5.16.15.json index f8160914..e2b2188c 100644 --- a/packages/starter-astro/stats/5.16.15.json +++ b/packages/starter-astro/stats/5.16.15.json @@ -27,6 +27,7 @@ }, "prodDependencies": 1, "devDependencies": 2, + "allDependencies": 0, "duplicateDependencies": 17, "depInstallSize": 171119612, "e18eMessages": [ diff --git a/packages/starter-mastro/ci-stats.json b/packages/starter-mastro/ci-stats.json index b1d49c74..c7d17cd0 100644 --- a/packages/starter-mastro/ci-stats.json +++ b/packages/starter-mastro/ci-stats.json @@ -22,6 +22,7 @@ "buildOutputSize": 12288, "prodDependencies": 2, "devDependencies": 2, + "allDependencies": 0, "duplicateDependencies": 0, "depInstallSize": 28724892, "e18eMessages": [], diff --git a/packages/starter-next-js/ci-stats.json b/packages/starter-next-js/ci-stats.json index d6a9febd..b38ad2e4 100644 --- a/packages/starter-next-js/ci-stats.json +++ b/packages/starter-next-js/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 3, "devDependencies": 6, + "allDependencies": 0, "duplicateDependencies": 12, "depInstallSize": 530810717, "e18eMessages": [ diff --git a/packages/starter-next-js/stats/16.1.1.json b/packages/starter-next-js/stats/16.1.1.json index d6a9febd..b38ad2e4 100644 --- a/packages/starter-next-js/stats/16.1.1.json +++ b/packages/starter-next-js/stats/16.1.1.json @@ -27,6 +27,7 @@ }, "prodDependencies": 3, "devDependencies": 6, + "allDependencies": 0, "duplicateDependencies": 12, "depInstallSize": 530810717, "e18eMessages": [ diff --git a/packages/starter-nuxt/ci-stats.json b/packages/starter-nuxt/ci-stats.json index 9693c3f8..5cac3263 100644 --- a/packages/starter-nuxt/ci-stats.json +++ b/packages/starter-nuxt/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 3, "devDependencies": 2, + "allDependencies": 0, "duplicateDependencies": 63, "depInstallSize": 180604928, "e18eMessages": [ diff --git a/packages/starter-nuxt/stats/4.2.2.json b/packages/starter-nuxt/stats/4.2.2.json index 9693c3f8..5cac3263 100644 --- a/packages/starter-nuxt/stats/4.2.2.json +++ b/packages/starter-nuxt/stats/4.2.2.json @@ -27,6 +27,7 @@ }, "prodDependencies": 3, "devDependencies": 2, + "allDependencies": 0, "duplicateDependencies": 63, "depInstallSize": 180604928, "e18eMessages": [ diff --git a/packages/starter-react-router/ci-stats.json b/packages/starter-react-router/ci-stats.json index 510fe4a2..eef733de 100644 --- a/packages/starter-react-router/ci-stats.json +++ b/packages/starter-react-router/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 6, "devDependencies": 8, + "allDependencies": 0, "duplicateDependencies": 9, "depInstallSize": 107182276, "e18eMessages": [ diff --git a/packages/starter-react-router/stats/7.10.1.json b/packages/starter-react-router/stats/7.10.1.json index 510fe4a2..eef733de 100644 --- a/packages/starter-react-router/stats/7.10.1.json +++ b/packages/starter-react-router/stats/7.10.1.json @@ -27,6 +27,7 @@ }, "prodDependencies": 6, "devDependencies": 8, + "allDependencies": 0, "duplicateDependencies": 9, "depInstallSize": 107182276, "e18eMessages": [ diff --git a/packages/starter-solid-start/ci-stats.json b/packages/starter-solid-start/ci-stats.json index 743c3f01..a2bbec49 100644 --- a/packages/starter-solid-start/ci-stats.json +++ b/packages/starter-solid-start/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 5, "devDependencies": 0, + "allDependencies": 0, "duplicateDependencies": 79, "depInstallSize": 143557200, "e18eMessages": [ diff --git a/packages/starter-solid-start/stats/1.2.1.json b/packages/starter-solid-start/stats/1.2.1.json index 743c3f01..a2bbec49 100644 --- a/packages/starter-solid-start/stats/1.2.1.json +++ b/packages/starter-solid-start/stats/1.2.1.json @@ -27,6 +27,7 @@ }, "prodDependencies": 5, "devDependencies": 0, + "allDependencies": 0, "duplicateDependencies": 79, "depInstallSize": 143557200, "e18eMessages": [ diff --git a/packages/starter-sveltekit/ci-stats.json b/packages/starter-sveltekit/ci-stats.json index 05f41e5b..1ba243d0 100644 --- a/packages/starter-sveltekit/ci-stats.json +++ b/packages/starter-sveltekit/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 0, "devDependencies": 7, + "allDependencies": 0, "duplicateDependencies": 1, "depInstallSize": 68539509, "e18eMessages": [ diff --git a/packages/starter-sveltekit/stats/2.49.4.json b/packages/starter-sveltekit/stats/2.49.4.json index 05f41e5b..1ba243d0 100644 --- a/packages/starter-sveltekit/stats/2.49.4.json +++ b/packages/starter-sveltekit/stats/2.49.4.json @@ -27,6 +27,7 @@ }, "prodDependencies": 0, "devDependencies": 7, + "allDependencies": 0, "duplicateDependencies": 1, "depInstallSize": 68539509, "e18eMessages": [ diff --git a/packages/starter-tanstack-start-react/ci-stats.json b/packages/starter-tanstack-start-react/ci-stats.json index 453d08af..6f1d7fa7 100644 --- a/packages/starter-tanstack-start-react/ci-stats.json +++ b/packages/starter-tanstack-start-react/ci-stats.json @@ -27,6 +27,7 @@ }, "prodDependencies": 13, "devDependencies": 11, + "allDependencies": 0, "duplicateDependencies": 14, "depInstallSize": 208163833, "e18eMessages": [ diff --git a/packages/starter-tanstack-start-react/stats/1.145.3.json b/packages/starter-tanstack-start-react/stats/1.145.3.json index 453d08af..6f1d7fa7 100644 --- a/packages/starter-tanstack-start-react/stats/1.145.3.json +++ b/packages/starter-tanstack-start-react/stats/1.145.3.json @@ -27,6 +27,7 @@ }, "prodDependencies": 13, "devDependencies": 11, + "allDependencies": 0, "duplicateDependencies": 14, "depInstallSize": 208163833, "e18eMessages": [ diff --git a/packages/stats-generator/src/collect-stats.ts b/packages/stats-generator/src/collect-stats.ts index 007d83db..a571a118 100644 --- a/packages/stats-generator/src/collect-stats.ts +++ b/packages/stats-generator/src/collect-stats.ts @@ -4,24 +4,13 @@ import { getFrameworks } from './get-frameworks.ts' import { packagesDir } from './constants.ts' import { saveStats } from './save-stats.ts' import { getCIStats } from './get-ci-stats.ts' +import { getDependencyCountsFromPackageMetadata } from './utils.ts' import type { BrowserBaselineStats, FrameworkStats, - PackageJson, FrameworkConfig, } from './types.ts' -async function getDependencyCountsFromPackageJson(pkgDir: string) { - const packageJsonPath = join(packagesDir, pkgDir, 'package.json') - const content = await readFile(packageJsonPath, 'utf-8') - const packageJson = JSON.parse(content) as PackageJson - - return { - prodDependencies: Object.keys(packageJson.dependencies ?? {}).length, - devDependencies: Object.keys(packageJson.devDependencies ?? {}).length, - } -} - async function getBrowserBaselineStats(pkgDir: string) { const browserBaselineStatsPath = join( packagesDir, @@ -51,8 +40,11 @@ async function processStarter(framework: FrameworkConfig, order: number) { const hasDependencies = measurements.some((m) => m.type === 'dependencies') const dependencyStats = - hasDependencies && ciStats.prodDependencies === undefined - ? await getDependencyCountsFromPackageJson(pkgDir) + hasDependencies && + (ciStats.prodDependencies === undefined || + ciStats.devDependencies === undefined || + ciStats.allDependencies === undefined) + ? getDependencyCountsFromPackageMetadata(pkgDir) : {} const hasBrowserBaseline = measurements.some( (m) => m.type === 'browserBaseline', diff --git a/packages/stats-generator/src/save-ci-stats.ts b/packages/stats-generator/src/save-ci-stats.ts index ec742baf..266b13d3 100644 --- a/packages/stats-generator/src/save-ci-stats.ts +++ b/packages/stats-generator/src/save-ci-stats.ts @@ -1,7 +1,12 @@ import { join } from 'node:path' import { getFrameworks } from './get-frameworks.ts' import { packagesDir } from './constants.ts' -import { normalizeCIStats, readJsonFile, writeJsonFile } from './utils.ts' +import { + getDependencyCountsFromPackageMetadata, + normalizeCIStats, + readJsonFile, + writeJsonFile, +} from './utils.ts' import type { CIStats, InstallStats, @@ -134,13 +139,19 @@ async function main() { const e18eStats = readJsonFile(e18eArtifactPath) if (e18eStats) { console.info(` ✓ Found e18e stats artifact`) + const packageDependencyCounts = + getDependencyCountsFromPackageMetadata(packageName) const duplicateEntry = e18eStats.stats.extraStats?.find( (s) => s.name === 'duplicateDependencyCount', ) - stats = { - ...stats, + const dependencyCounts = { prodDependencies: e18eStats.stats.dependencyCount.production, devDependencies: e18eStats.stats.dependencyCount.development, + allDependencies: packageDependencyCounts.allDependencies, + } + stats = { + ...stats, + ...dependencyCounts, duplicateDependencies: typeof duplicateEntry?.value === 'number' ? duplicateEntry.value diff --git a/packages/stats-generator/src/types.ts b/packages/stats-generator/src/types.ts index 1f738fd6..f958fd93 100644 --- a/packages/stats-generator/src/types.ts +++ b/packages/stats-generator/src/types.ts @@ -101,6 +101,7 @@ export interface CIStats { // Dependency stats (from e18e analysis) prodDependencies?: number devDependencies?: number + allDependencies?: number duplicateDependencies?: number depInstallSize?: number e18eMessages?: Array<{ diff --git a/packages/stats-generator/src/utils.ts b/packages/stats-generator/src/utils.ts index 80ec7d90..18fcb615 100644 --- a/packages/stats-generator/src/utils.ts +++ b/packages/stats-generator/src/utils.ts @@ -4,7 +4,12 @@ import { readFile } from 'node:fs/promises' import { join, dirname } from 'node:path' import { packagesDir } from './constants.ts' import { getFrameworks } from './get-frameworks.ts' -import type { CIStats, FrameworkConfig, TestConfig } from './types.ts' +import type { + CIStats, + FrameworkConfig, + PackageJson, + TestConfig, +} from './types.ts' /** * Get directory size in bytes using du command. @@ -48,6 +53,46 @@ export function writeJsonFile(filePath: string, data: unknown): void { writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`) } +function countPnpmLockPackages(lockfileContent: string): number { + const packageEntryPattern = /^ {2}\S.*:\s*$/ + const lines = lockfileContent.split(/\r?\n/) + const packagesIndex = lines.findIndex((line) => line === 'packages:') + if (packagesIndex === -1) { + return 0 + } + + let count = 0 + for (const line of lines.slice(packagesIndex + 1)) { + if (/^\S/.test(line)) { + break + } + + if (packageEntryPattern.test(line)) { + count += 1 + } + } + + return count +} + +export function getDependencyCountsFromPackageMetadata(packageName: string) { + const packageJsonPath = join(packagesDir, packageName, 'package.json') + const packageJson = JSON.parse( + readFileSync(packageJsonPath, 'utf-8'), + ) as PackageJson + + const lockfilePath = join(packagesDir, packageName, 'pnpm-lock.yaml') + const allDependencies = existsSync(lockfilePath) + ? countPnpmLockPackages(readFileSync(lockfilePath, 'utf-8')) + : undefined + + return { + prodDependencies: Object.keys(packageJson.dependencies ?? {}).length, + devDependencies: Object.keys(packageJson.devDependencies ?? {}).length, + allDependencies, + } +} + export async function getFrameworkVersion( packageName: string, frameworkPackage: string,