@@ -12,8 +12,9 @@ import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "
1212import https from "node:https" ;
1313import { join } from "node:path" ;
1414
15- const DASHBOARD_PACKAGE_PATH = join ( process . cwd ( ) , "apps/dashboard/package.json" ) ;
16- const DIST_PATH = join ( process . cwd ( ) , "apps/dashboard/dist" ) ;
15+ const DASHBOARD_DIR = join ( process . cwd ( ) , "apps/dashboard" ) ;
16+ const WORKSPACE_PATH = join ( process . cwd ( ) , "pnpm-workspace.yaml" ) ;
17+ const DIST_PATH = join ( DASHBOARD_DIR , "dist" ) ;
1718const STATS_OUTPUT_PATH = join ( process . cwd ( ) , "data/vite-version-stats.json" ) ;
1819
1920/**
@@ -87,56 +88,64 @@ async function fetchNpmPublicationDates() {
8788 } ) ;
8889}
8990
91+ // Matches the `vite:` entry inside the top-level `overrides:` block of
92+ // pnpm-workspace.yaml (the quoted form is unique to overrides; the catalog
93+ // entry uses an unquoted `npm:` alias).
94+ const OVERRIDE_VITE_RE = / ^ ( o v e r r i d e s : \n (?: .* \n ) * ?[ \t ] + v i t e : ) " [ ^ " ] * " / m;
95+
9096/**
91- * Get the current Vite version from package.json
92- * @returns {string } Current version string
97+ * Get the current overridden Vite version from pnpm-workspace.yaml
98+ * @returns {string } Current override value (e.g. "catalog:" or "8.0.0")
9399 */
94100function getCurrentVersion ( ) {
95101 try {
96- const packageJson = JSON . parse ( readFileSync ( DASHBOARD_PACKAGE_PATH , "utf8" ) ) ;
97- return packageJson . devDependencies [ "vite" ] ;
102+ const workspace = readFileSync ( WORKSPACE_PATH , "utf8" ) ;
103+ const match = workspace . match ( OVERRIDE_VITE_RE ) ;
104+ return match ? match [ 0 ] . split ( '"' ) [ 1 ] : "" ;
98105 } catch ( error ) {
99- console . error ( "Error reading package.json :" , error . message ) ;
106+ console . error ( "Error reading pnpm-workspace.yaml :" , error . message ) ;
100107 process . exit ( 1 ) ;
101108 // Unreachable return to satisfy consistent-return linter rule
102109 return "" ;
103110 }
104111}
105112
106113/**
107- * Update the Vite version in package.json
108- * @param {string } version - Target version to update to
114+ * Pin the Vite version via the pnpm `overrides` entry in pnpm-workspace.yaml.
115+ * Vite+ resolves the `vite` dependency through this override, so this is the
116+ * supported way to build the dashboard against a specific Vite release.
117+ * @param {string } version - Target version to pin (e.g. "8.0.0")
109118 * @returns {boolean } Success status
110119 */
111120function updateViteVersion ( version ) {
112121 try {
113- console . log ( `📦 Updating vite to version: ${ version } ` ) ;
114-
115- // Read current package.json
116- const packageJson = JSON . parse ( readFileSync ( DASHBOARD_PACKAGE_PATH , "utf8" ) ) ;
122+ console . log ( `📦 Overriding vite to version: ${ version } ` ) ;
117123
118- // Update vite version
119- packageJson . devDependencies [ "vite" ] = version ;
124+ const workspace = readFileSync ( WORKSPACE_PATH , "utf8" ) ;
125+ if ( ! OVERRIDE_VITE_RE . test ( workspace ) ) {
126+ console . error ( "❌ Could not find a `vite` entry under `overrides:` in pnpm-workspace.yaml" ) ;
127+ return false ;
128+ }
120129
121- // Write back to package.json
122- writeFileSync ( DASHBOARD_PACKAGE_PATH , JSON . stringify ( packageJson , null , 2 ) + "\n" ) ;
130+ const updated = workspace . replace ( OVERRIDE_VITE_RE , `$1" ${ version } "` ) ;
131+ writeFileSync ( WORKSPACE_PATH , updated ) ;
123132
124- console . log ( "✅ Package.json updated successfully" ) ;
133+ console . log ( "✅ pnpm-workspace.yaml override updated successfully" ) ;
125134 return true ;
126135 } catch ( error ) {
127- console . error ( "❌ Error updating package.json :" , error . message ) ;
136+ console . error ( "❌ Error updating pnpm-workspace.yaml :" , error . message ) ;
128137 return false ;
129138 }
130139}
131140
132141/**
133- * Install dependencies using pnpm
142+ * Install dependencies using Vite+
134143 * @returns {boolean } Success status
135144 */
136145function installDependencies ( ) {
137146 try {
138147 console . log ( "📥 Installing dependencies..." ) ;
139- execSync ( "pnpm install --no-frozen-lockfile" , {
148+ execSync ( "vp install --no-frozen-lockfile" , {
140149 stdio : "inherit" ,
141150 cwd : process . cwd ( ) ,
142151 env : process . env ,
@@ -145,24 +154,24 @@ function installDependencies() {
145154 return true ;
146155 } catch ( error ) {
147156 console . error ( "❌ Error installing dependencies:" , error . message ) ;
148- console . error ( "❌ Aborting due to pnpm install failure" ) ;
157+ console . error ( "❌ Aborting due to install failure" ) ;
149158 process . exit ( 1 ) ;
150159 // Unreachable return to satisfy consistent-return linter rule
151160 return false ;
152161 }
153162}
154163
155164/**
156- * Build the application using Vite
165+ * Build the application using Vite+
157166 * @returns {{ success: boolean, buildTime: number | null } } Build result with timing
158167 */
159168function buildApp ( ) {
160169 try {
161170 console . log ( "🔨 Building application..." ) ;
162171 const startTime = Date . now ( ) ;
163- execSync ( "./node_modules/vite/bin/vite.js build" , {
172+ execSync ( "vp build" , {
164173 stdio : "inherit" ,
165- cwd : join ( process . cwd ( ) , "apps/dashboard" ) ,
174+ cwd : DASHBOARD_DIR ,
166175 } ) ;
167176 const buildTime = Date . now ( ) - startTime ;
168177 console . log ( `✅ Build completed successfully in ${ buildTime } ms` ) ;
@@ -173,6 +182,40 @@ function buildApp() {
173182 }
174183}
175184
185+ /**
186+ * Recursively list files under a directory with their sizes and types
187+ * @param {string } dir - Directory to walk
188+ * @param {string } baseDir - Relative path prefix for collected entries
189+ * @returns {Array<{ path: string, size: number, type: string }> } File entries
190+ */
191+ function getFilesRecursively ( dir , baseDir = "" ) {
192+ const files = [ ] ;
193+ const items = readdirSync ( dir ) ;
194+
195+ for ( const item of items ) {
196+ const fullPath = join ( dir , item ) ;
197+ const relativePath = join ( baseDir , item ) ;
198+ const stat = statSync ( fullPath ) ;
199+
200+ if ( stat . isDirectory ( ) ) {
201+ files . push ( ...getFilesRecursively ( fullPath , relativePath ) ) ;
202+ } else {
203+ files . push ( {
204+ path : relativePath ,
205+ size : stat . size ,
206+ type : item . endsWith ( ".js" )
207+ ? "js"
208+ : item . endsWith ( ".css" )
209+ ? "css"
210+ : item . endsWith ( ".html" )
211+ ? "html"
212+ : "other" ,
213+ } ) ;
214+ }
215+ }
216+ return files ;
217+ }
218+
176219/**
177220 * Collect file statistics from the dist directory
178221 * @param {string } version - Vite version
@@ -196,35 +239,6 @@ function collectDistStats(version, buildTime = null, publicationDate = null) {
196239 }
197240
198241 try {
199- // Get all files recursively
200- function getFilesRecursively ( dir , baseDir = "" ) {
201- const files = [ ] ;
202- const items = readdirSync ( dir ) ;
203-
204- for ( const item of items ) {
205- const fullPath = join ( dir , item ) ;
206- const relativePath = join ( baseDir , item ) ;
207- const stat = statSync ( fullPath ) ;
208-
209- if ( stat . isDirectory ( ) ) {
210- files . push ( ...getFilesRecursively ( fullPath , relativePath ) ) ;
211- } else {
212- files . push ( {
213- path : relativePath ,
214- size : stat . size ,
215- type : item . endsWith ( ".js" )
216- ? "js"
217- : item . endsWith ( ".css" )
218- ? "css"
219- : item . endsWith ( ".html" )
220- ? "html"
221- : "other" ,
222- } ) ;
223- }
224- }
225- return files ;
226- }
227-
228242 stats . files = getFilesRecursively ( DIST_PATH ) ;
229243 stats . totalSize = stats . files . reduce ( ( total , file ) => total + file . size , 0 ) ;
230244
@@ -293,8 +307,8 @@ async function collectAllVersionStats() {
293307
294308 console . log ( `📦 Found ${ stableVersions . length } versions to analyze` ) ;
295309
296- // Store original package.json for restoration
297- const originalPackageJson = readFileSync ( DASHBOARD_PACKAGE_PATH , "utf8" ) ;
310+ // Store original pnpm-workspace.yaml for restoration
311+ const originalWorkspace = readFileSync ( WORKSPACE_PATH , "utf8" ) ;
298312
299313 for ( let i = 0 ; i < stableVersions . length ; i ++ ) {
300314 const version = stableVersions [ i ] ;
@@ -308,7 +322,7 @@ async function collectAllVersionStats() {
308322 try {
309323 // Update version
310324 if ( ! updateViteVersion ( version ) ) {
311- console . error ( `❌ Failed to update package.json for version ${ version } ` ) ;
325+ console . error ( `❌ Failed to override vite version ${ version } ` ) ;
312326 failureCount ++ ;
313327 continue ;
314328 }
@@ -341,9 +355,10 @@ async function collectAllVersionStats() {
341355 }
342356 }
343357
344- // Restore original package.json
345- console . log ( "\n🔄 Restoring original package.json..." ) ;
346- writeFileSync ( DASHBOARD_PACKAGE_PATH , originalPackageJson ) ;
358+ // Restore original pnpm-workspace.yaml and reinstall to reset the lockfile
359+ console . log ( "\n🔄 Restoring original pnpm-workspace.yaml..." ) ;
360+ writeFileSync ( WORKSPACE_PATH , originalWorkspace ) ;
361+ installDependencies ( ) ;
347362
348363 // Save results. Skip writing an empty dataset (e.g. when no stable Vite 8
349364 // release exists yet) so we don't clobber the existing tracked stats and
0 commit comments