Skip to content

Commit 600bc95

Browse files
authored
fix: build per-version Vite stats through the vite-plus toolchain (#185)
The stats generator was still written for the old plain-Vite setup and no longer worked after the vite-plus migration: - It set devDependencies.vite in apps/dashboard/package.json, but the dashboard depends on vite-plus and the Vite version is resolved via the `overrides` entry in pnpm-workspace.yaml. - It built with ./node_modules/vite/bin/vite.js, which no longer exists. - It shelled out to pnpm directly instead of vp. Pin the target Vite version through the pnpm `overrides` entry, install with `vp install`, and build with `vp build`. Restore pnpm-workspace.yaml afterward. Also hoist getFilesRecursively to module scope to clear a lint warning.
1 parent fb8f058 commit 600bc95

1 file changed

Lines changed: 75 additions & 60 deletions

File tree

tools/override-vite.mjs

Lines changed: 75 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "
1212
import https from "node:https";
1313
import { 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");
1718
const 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 = /^(overrides:\n(?:.*\n)*?[ \t]+vite: )"[^"]*"/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
*/
94100
function 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
*/
111120
function 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
*/
136145
function 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
*/
159168
function 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

Comments
 (0)