Skip to content

Commit 7dfc509

Browse files
authored
refactor(cli): simplify vp --version by using generated versions module (#1164)
ref: #1162 (comment) This branch is derrived from #1162
1 parent ab7f106 commit 7dfc509

1 file changed

Lines changed: 34 additions & 114 deletions

File tree

packages/cli/src/version.ts

Lines changed: 34 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,36 @@
11
import fs from 'node:fs';
2-
import { createRequire } from 'node:module';
32
import path from 'node:path';
43

54
import { vitePlusHeader } from '../binding/index.js';
5+
import cliPkg from '../package.json' with { type: 'json' };
66
import { VITE_PLUS_NAME } from './utils/constants.js';
77
import { renderCliDoc } from './utils/help.js';
88
import { detectPackageMetadata, hasVitePlusDependency } from './utils/package.js';
99
import { accent, log } from './utils/terminal.js';
1010

11-
const require = createRequire(import.meta.url);
12-
13-
interface PackageJson {
14-
version?: string;
15-
bundledVersions?: Record<string, string>;
16-
dependencies?: Record<string, string>;
17-
devDependencies?: Record<string, string>;
18-
}
11+
/** Tool display names in the order shown by `vp --version`. */
12+
const TOOL_DISPLAY_ORDER = [
13+
'vite',
14+
'rolldown',
15+
'vitest',
16+
'oxfmt',
17+
'oxlint',
18+
'oxlint-tsgolint',
19+
'tsdown',
20+
] as const;
1921

2022
interface LocalPackageMetadata {
2123
name: string;
2224
version: string;
2325
path: string;
2426
}
2527

26-
interface ToolVersionSpec {
27-
displayName: string;
28-
packageName: string;
29-
bundledVersionKey?: string;
30-
fallbackPackageJson?: string;
31-
}
32-
3328
function getGlobalVersion(): string | null {
3429
return process.env.VP_GLOBAL_VERSION ?? null;
3530
}
3631

3732
function getCliVersion(): string | null {
38-
const pkg = resolvePackageJson(VITE_PLUS_NAME, process.cwd());
39-
return pkg?.version ?? null;
33+
return cliPkg.version ?? null;
4034
}
4135

4236
function getLocalMetadata(cwd: string): LocalPackageMetadata | null {
@@ -50,9 +44,13 @@ function isVitePlusDeclaredInAncestors(cwd: string): boolean {
5044
let currentDir = path.resolve(cwd);
5145
while (true) {
5246
const packageJsonPath = path.join(currentDir, 'package.json');
53-
const pkg = readPackageJsonFromPath(packageJsonPath);
54-
if (pkg && hasVitePlusDependency(pkg)) {
55-
return true;
47+
try {
48+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
49+
if (hasVitePlusDependency(pkg)) {
50+
return true;
51+
}
52+
} catch {
53+
// no package.json at this level
5654
}
5755
const parentDir = path.dirname(currentDir);
5856
if (parentDir === currentDir) {
@@ -63,60 +61,20 @@ function isVitePlusDeclaredInAncestors(cwd: string): boolean {
6361
return false;
6462
}
6563

66-
function readPackageJsonFromPath(packageJsonPath: string): PackageJson | null {
67-
try {
68-
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as PackageJson;
69-
} catch {
70-
return null;
71-
}
72-
}
73-
74-
function resolvePackageJson(packageName: string, baseDir: string): PackageJson | null {
64+
/**
65+
* Resolve all tool versions from the locally installed vite-plus package.
66+
* Uses the `vite-plus/versions` export generated by `syncVersionsExport()`.
67+
*/
68+
async function resolveToolVersions(localPackagePath: string): Promise<Record<string, string>> {
7569
try {
76-
// Try resolving package.json subpath directly
77-
const packageJsonPath = require.resolve(`${packageName}/package.json`, {
78-
paths: [baseDir],
79-
});
80-
return readPackageJsonFromPath(packageJsonPath);
81-
} catch {
82-
// Fallback for packages with restricted exports that don't expose ./package.json:
83-
// resolve the main entry and find package.json relative to it
84-
try {
85-
const mainPath = require.resolve(packageName, { paths: [baseDir] });
86-
// Walk up from the resolved entry to find the package.json
87-
let dir = path.dirname(mainPath);
88-
while (dir !== path.dirname(dir)) {
89-
const pkgPath = path.join(dir, 'package.json');
90-
const pkg = readPackageJsonFromPath(pkgPath);
91-
if (pkg) {
92-
return pkg;
93-
}
94-
dir = path.dirname(dir);
95-
}
96-
} catch {
97-
// package not found at all
70+
const mod = await import(`${localPackagePath}/dist/versions.js`);
71+
if (mod.versions && typeof mod.versions === 'object') {
72+
return mod.versions as Record<string, string>;
9873
}
99-
return null;
100-
}
101-
}
102-
103-
function resolveToolVersion(tool: ToolVersionSpec, localPackagePath: string): string | null {
104-
const pkg = resolvePackageJson(tool.packageName, localPackagePath);
105-
const bundledVersion = tool.bundledVersionKey
106-
? (pkg?.bundledVersions?.[tool.bundledVersionKey] ?? null)
107-
: null;
108-
if (bundledVersion) {
109-
return bundledVersion;
110-
}
111-
const version = pkg?.version ?? null;
112-
if (version) {
113-
return version;
114-
}
115-
if (tool.fallbackPackageJson) {
116-
const fallbackPath = path.join(localPackagePath, tool.fallbackPackageJson);
117-
return readPackageJsonFromPath(fallbackPath)?.version ?? null;
74+
} catch {
75+
// versions module not available
11876
}
119-
return null;
77+
return {};
12078
}
12179

12280
/**
@@ -145,52 +103,14 @@ export async function printVersion(cwd: string) {
145103
},
146104
];
147105

148-
const tools: ToolVersionSpec[] = [
149-
{
150-
displayName: 'vite',
151-
packageName: '@voidzero-dev/vite-plus-core',
152-
bundledVersionKey: 'vite',
153-
},
154-
{
155-
displayName: 'rolldown',
156-
packageName: '@voidzero-dev/vite-plus-core',
157-
bundledVersionKey: 'rolldown',
158-
},
159-
{
160-
displayName: 'vitest',
161-
packageName: '@voidzero-dev/vite-plus-test',
162-
bundledVersionKey: 'vitest',
163-
},
164-
{
165-
displayName: 'oxfmt',
166-
packageName: 'oxfmt',
167-
},
168-
{
169-
displayName: 'oxlint',
170-
packageName: 'oxlint',
171-
},
172-
{
173-
displayName: 'oxlint-tsgolint',
174-
packageName: 'oxlint-tsgolint',
175-
},
176-
{
177-
displayName: 'tsdown',
178-
packageName: '@voidzero-dev/vite-plus-core',
179-
bundledVersionKey: 'tsdown',
180-
},
181-
];
182-
183106
if (localMetadata) {
184-
const resolvedTools = tools.map((tool) => ({
185-
tool,
186-
version: resolveToolVersion(tool, localMetadata.path),
187-
}));
107+
const versions = await resolveToolVersions(localMetadata.path);
188108

189109
sections.push({
190110
title: 'Tools',
191-
rows: resolvedTools.map(({ tool, version }) => ({
192-
label: accent(tool.displayName),
193-
description: version ? `v${version}` : 'Not found',
111+
rows: TOOL_DISPLAY_ORDER.map((name) => ({
112+
label: accent(name),
113+
description: versions[name] ? `v${versions[name]}` : 'Not found',
194114
})),
195115
});
196116
}

0 commit comments

Comments
 (0)