vite-plus 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/LICENSE +1 -849
- package/README.md +1 -1
- package/bin/vpx +9 -0
- package/binding/index.cjs +59 -54
- package/binding/index.d.cts +132 -2
- package/dist/{agent-KeDc6vmg.js → agent-D8oxxhVR.js} +7 -9
- package/dist/bin.js +27 -34
- package/dist/{cli-parse-DHE8NrBU.js → cli-parse-aeUeFDlC.js} +2 -3
- package/dist/command-TjS_6y9O.js +1 -0
- package/dist/{command-CguLh2KL.js → command-rY79K5NI.js} +40 -42
- package/dist/{comparison-CmVirWIW-DUGaiYqF.js → comparison-CmVirWIW-UlEf2maz.js} +1 -2
- package/dist/config/bin.js +8 -10
- package/dist/{constants-BW3g7VnD.js → constants-DRUnJ_Dz.js} +4 -6
- package/dist/create/bin.d.ts +4 -8
- package/dist/create/bin.js +64 -68
- package/dist/{define-config-CIlk9scU.js → define-config-ChwJcu5e.js} +6 -9
- package/dist/{define-config-Dq_23Eyr.cjs → define-config-Cv2P6NT2.cjs} +8 -13
- package/dist/{define-config-Bexdd6RZ.d.ts → define-config-rPhYIFSn.d.ts} +1 -11
- package/dist/define-config.cjs +1 -1
- package/dist/define-config.d.ts +1 -1
- package/dist/define-config.js +1 -1
- package/dist/{dist-Bi7ZEK3c.js → dist-Bs0SObNC.js} +77 -149
- package/dist/{dist-Cqz8OtiO.js → dist-CdkMvIiQ.js} +11 -5
- package/dist/dist-zDZV5eEc.js +3 -0
- package/dist/{documentation-DqcZSthV.js → documentation-cv_y0Auv.js} +1 -2
- package/dist/{editor-b1XUwt9v.js → editor-ClL78D8u.js} +1492 -4211
- package/dist/{help-BmKpeOP9.js → help-B03t_iQ4.js} +1 -2
- package/dist/hooks/bin.js +4 -5
- package/dist/{hooks-DhwsWb46.js → hooks-xRcJPc-O.js} +5 -4
- package/dist/index.cjs +2 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{json-JP24qHUF.js → json-kl84kDyH.js} +9 -18
- package/dist/lint-plugins.cjs +1 -1
- package/dist/migration/bin.js +719 -184
- package/dist/migration/compat/worker.js +4 -6
- package/dist/{oxlint-plugin-config-Dx-ZY2MN.js → oxlint-plugin-config-BVpqYdcC.js} +3 -4
- package/dist/oxlint-plugin.d.ts +0 -2
- package/dist/oxlint-plugin.js +6 -7
- package/dist/{pack-BK38MLVZ.d.ts → pack-ARPFMefW.d.ts} +0 -2
- package/dist/pack-bin.d.ts +1 -3
- package/dist/pack-bin.js +3 -4
- package/dist/pack.d.ts +1 -1
- package/dist/{package-BP16iQby.js → package-DzsomcUD.js} +10 -95
- package/dist/{package-overrides-D1RcXSFl.js → package-overrides-Ci8GXouY.js} +5 -8
- package/dist/picomatch-DEUoj81q.js +1916 -0
- package/dist/{prompts-BGpQtC5z.js → prompts-GL1vj0wk.js} +113 -239
- package/dist/{protocol-D99W10Qi.js → protocol-CkNmY-Mr.js} +1 -2
- package/dist/{report-NhQk8VHb.js → report-DLHO30yZ.js} +2 -2
- package/dist/{resolve-vite-config-x47JetlI.js → resolve-vite-config-Dn5896A4.js} +9 -25
- package/dist/resolve-vite-config-QO6cC0SP.js +1 -0
- package/dist/{rolldown-runtime-CMFfr-1z.js → rolldown-runtime-DegdyBIC.js} +2 -3
- package/dist/script-esm-hooks.d.ts +8 -0
- package/dist/script-esm-hooks.js +24 -0
- package/dist/script-hooks-9Fof5UMY.js +176 -0
- package/dist/script-preload.cjs +468 -0
- package/dist/script-register.d.ts +1 -0
- package/dist/script-register.js +22 -0
- package/dist/script-watch.d.ts +1 -0
- package/dist/script-watch.js +1908 -0
- package/dist/staged/bin.js +81 -2011
- package/dist/sync-versions/bin.js +29 -50
- package/dist/sync-versions/bin.mjs +117 -224
- package/dist/{terminal-MKGAuy-p.js → terminal-BcuPUy-j.js} +1 -2
- package/dist/toolchain.js +36 -10
- package/dist/toolchain.json +36 -10
- package/dist/{tsconfig-C5PnJfW4.js → tsconfig-Do6MAG_f.js} +1 -1
- package/dist/{tsconfig-D2DzAQ_D.js → tsconfig-LE_mAwe_.js} +8 -10
- package/dist/version.d.ts +1 -3
- package/dist/version.js +5 -6
- package/dist/versions.js +5 -5
- package/dist/{vitest-ecosystem-BU0AqZq-.js → vitest-ecosystem-BeEYz-qF.js} +1 -2
- package/dist/{vitest-v5-entry-points-DthU1e_O.js → vitest-v5-entry-points-NyJsFeux.js} +1 -2
- package/dist/vpx-bin.d.ts +1 -0
- package/dist/vpx-bin.js +232 -0
- package/dist/vpx-script-EXgV5QOf.js +434 -0
- package/docs/config/run.md +4 -0
- package/docs/guide/check.md +1 -0
- package/docs/guide/ci.md +13 -3
- package/docs/guide/create.md +34 -0
- package/docs/guide/env.md +27 -13
- package/docs/guide/global-cli.md +52 -0
- package/docs/guide/local-cli.md +4 -4
- package/docs/guide/migrate-rules.md +48 -5
- package/docs/guide/migrate.md +6 -6
- package/docs/guide/package-management.md +19 -2
- package/docs/guide/test.md +1 -1
- package/docs/guide/vitest-v5.md +2 -2
- package/docs/guide/vpx.md +170 -9
- package/package.json +32 -29
- package/dist/command-DaRqSNpP.js +0 -1
- package/dist/dist-CBWGibx8.js +0 -3
- package/dist/resolve-vite-config-CGzlyhGr.js +0 -1
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { accessSync, closeSync, constants, openSync, readSync, statSync } from "node:fs";
|
|
3
|
+
// src/vpx-script.ts
|
|
4
|
+
/**
|
|
5
|
+
* Script detection for the project-local `vpx` bin. Mirrors the global CLI in
|
|
6
|
+
* `crates/vp_global_cli/src/commands/vpx_script.rs`; keep the two in sync.
|
|
7
|
+
*/
|
|
8
|
+
const SCRIPT_EXTENSIONS = [
|
|
9
|
+
".ts",
|
|
10
|
+
".mts",
|
|
11
|
+
".cts",
|
|
12
|
+
".tsx",
|
|
13
|
+
".js",
|
|
14
|
+
".mjs",
|
|
15
|
+
".cjs",
|
|
16
|
+
".jsx"
|
|
17
|
+
];
|
|
18
|
+
const TS_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
19
|
+
".ts",
|
|
20
|
+
".mts",
|
|
21
|
+
".cts",
|
|
22
|
+
".tsx"
|
|
23
|
+
]);
|
|
24
|
+
/** Node.js options that take a required value, which may come as the next argument (best effort). */
|
|
25
|
+
const NODE_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
|
|
26
|
+
"-C",
|
|
27
|
+
"-e",
|
|
28
|
+
"-p",
|
|
29
|
+
"-pe",
|
|
30
|
+
"-r",
|
|
31
|
+
"--allow-fs-read",
|
|
32
|
+
"--allow-fs-write",
|
|
33
|
+
"--build-sea",
|
|
34
|
+
"--build-snapshot-config",
|
|
35
|
+
"--conditions",
|
|
36
|
+
"--cpu-prof-dir",
|
|
37
|
+
"--cpu-prof-interval",
|
|
38
|
+
"--cpu-prof-name",
|
|
39
|
+
"--debug-port",
|
|
40
|
+
"--diagnostic-dir",
|
|
41
|
+
"--disable-proto",
|
|
42
|
+
"--disable-warning",
|
|
43
|
+
"--dns-result-order",
|
|
44
|
+
"--env-file",
|
|
45
|
+
"--env-file-if-exists",
|
|
46
|
+
"--eval",
|
|
47
|
+
"--experimental-config-file",
|
|
48
|
+
"--experimental-default-type",
|
|
49
|
+
"--experimental-loader",
|
|
50
|
+
"--experimental-package-map",
|
|
51
|
+
"--experimental-sea-config",
|
|
52
|
+
"--experimental-test-isolation",
|
|
53
|
+
"--experimental-test-tag-filter",
|
|
54
|
+
"--heap-prof-dir",
|
|
55
|
+
"--heap-prof-interval",
|
|
56
|
+
"--heap-prof-name",
|
|
57
|
+
"--heapsnapshot-near-heap-limit",
|
|
58
|
+
"--heapsnapshot-signal",
|
|
59
|
+
"--icu-data-dir",
|
|
60
|
+
"--import",
|
|
61
|
+
"--input-type",
|
|
62
|
+
"--inspect-port",
|
|
63
|
+
"--inspect-publish-uid",
|
|
64
|
+
"--loader",
|
|
65
|
+
"--localstorage-file",
|
|
66
|
+
"--max-http-header-size",
|
|
67
|
+
"--max-old-space-size-percentage",
|
|
68
|
+
"--network-family-autoselection-attempt-timeout",
|
|
69
|
+
"--openssl-config",
|
|
70
|
+
"--print",
|
|
71
|
+
"--redirect-warnings",
|
|
72
|
+
"--report-dir",
|
|
73
|
+
"--report-directory",
|
|
74
|
+
"--report-filename",
|
|
75
|
+
"--report-signal",
|
|
76
|
+
"--require",
|
|
77
|
+
"--run",
|
|
78
|
+
"--secure-heap",
|
|
79
|
+
"--secure-heap-min",
|
|
80
|
+
"--snapshot-blob",
|
|
81
|
+
"--test-concurrency",
|
|
82
|
+
"--test-coverage-branches",
|
|
83
|
+
"--test-coverage-exclude",
|
|
84
|
+
"--test-coverage-functions",
|
|
85
|
+
"--test-coverage-include",
|
|
86
|
+
"--test-coverage-lines",
|
|
87
|
+
"--test-global-setup",
|
|
88
|
+
"--test-isolation",
|
|
89
|
+
"--test-name-pattern",
|
|
90
|
+
"--test-random-seed",
|
|
91
|
+
"--test-reporter",
|
|
92
|
+
"--test-reporter-destination",
|
|
93
|
+
"--test-rerun-failures",
|
|
94
|
+
"--test-shard",
|
|
95
|
+
"--test-skip-pattern",
|
|
96
|
+
"--test-timeout",
|
|
97
|
+
"--title",
|
|
98
|
+
"--tls-cipher-list",
|
|
99
|
+
"--tls-keylog",
|
|
100
|
+
"--trace-event-categories",
|
|
101
|
+
"--trace-event-file-pattern",
|
|
102
|
+
"--trace-require-module",
|
|
103
|
+
"--unhandled-rejections",
|
|
104
|
+
"--use-largepages",
|
|
105
|
+
"--v8-pool-size",
|
|
106
|
+
"--watch-kill-signal",
|
|
107
|
+
"--watch-path"
|
|
108
|
+
]);
|
|
109
|
+
/**
|
|
110
|
+
* Node.js options after which positionals are not an entry file: the code of `--eval` /
|
|
111
|
+
* `--print` or the package script of `--run` runs instead, and `--test` takes test files
|
|
112
|
+
* and globs.
|
|
113
|
+
*/
|
|
114
|
+
const NODE_OPTIONS_WITHOUT_ENTRY = /* @__PURE__ */ new Set([
|
|
115
|
+
"-e",
|
|
116
|
+
"--eval",
|
|
117
|
+
"-p",
|
|
118
|
+
"-pe",
|
|
119
|
+
"--print",
|
|
120
|
+
"--run",
|
|
121
|
+
"--test"
|
|
122
|
+
]);
|
|
123
|
+
/**
|
|
124
|
+
* The watcher's options that take a value, which may come as the next argument, so that
|
|
125
|
+
* value is not taken for the script.
|
|
126
|
+
*/
|
|
127
|
+
const WATCH_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
|
|
128
|
+
"--exclude",
|
|
129
|
+
"--ignore",
|
|
130
|
+
"--include",
|
|
131
|
+
"--kill-signal",
|
|
132
|
+
"--kill-timeout"
|
|
133
|
+
]);
|
|
134
|
+
/**
|
|
135
|
+
* The option an argument names, without `=value`. Node.js accepts `_` for `-` in long
|
|
136
|
+
* option names, as in `--redirect_warnings`.
|
|
137
|
+
*/
|
|
138
|
+
function nodeOptionName(arg) {
|
|
139
|
+
const name = arg.split("=", 1)[0];
|
|
140
|
+
return name.startsWith("--") ? `--${name.slice(2).replaceAll("_", "-")}` : name;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Whether the option `name`, given without `=value`, takes `next` as its value. Node.js
|
|
144
|
+
* 24.19, 26.1, and later read a bare `--experimental-config-file` as `node.config.json`,
|
|
145
|
+
* and older releases take the next argument as the config file, so that argument is its
|
|
146
|
+
* value only when it is a `.json` file, which cannot be the script either way. Mirrors
|
|
147
|
+
* `takes_next_arg` in the global CLI.
|
|
148
|
+
*/
|
|
149
|
+
function takesNextArg(name, next) {
|
|
150
|
+
if (name === "--experimental-config-file") return next.endsWith(".json") && !next.startsWith("-");
|
|
151
|
+
return NODE_OPTIONS_WITH_VALUE.has(name) || WATCH_OPTIONS_WITH_VALUE.has(name);
|
|
152
|
+
}
|
|
153
|
+
/** npx-style: flags come before the first positional or unknown flag. */
|
|
154
|
+
function parseVpxArgs(args) {
|
|
155
|
+
const flags = {
|
|
156
|
+
packages: [],
|
|
157
|
+
shellMode: false,
|
|
158
|
+
silent: false,
|
|
159
|
+
help: false,
|
|
160
|
+
version: false
|
|
161
|
+
};
|
|
162
|
+
let index = 0;
|
|
163
|
+
for (; index < args.length; index++) {
|
|
164
|
+
const arg = args[index];
|
|
165
|
+
if (arg === "-p" || arg === "--package") {
|
|
166
|
+
index++;
|
|
167
|
+
if (index < args.length) flags.packages.push(args[index]);
|
|
168
|
+
} else if (arg.startsWith("--package=") || arg.startsWith("-p=")) flags.packages.push(arg.slice(arg.indexOf("=") + 1));
|
|
169
|
+
else if (arg === "-c" || arg === "--shell-mode") flags.shellMode = true;
|
|
170
|
+
else if (arg === "-s" || arg === "--silent") flags.silent = true;
|
|
171
|
+
else if (arg === "-h" || arg === "--help") flags.help = true;
|
|
172
|
+
else if (arg === "-v" || arg === "--version") flags.version = true;
|
|
173
|
+
else if (arg === "--tsconfig" && index + 1 < args.length) flags.tsconfig = args[++index];
|
|
174
|
+
else if (arg.startsWith("--tsconfig=")) flags.tsconfig = arg.slice(11);
|
|
175
|
+
else break;
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
flags,
|
|
179
|
+
positional: args.slice(index)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
var ScriptError = class extends Error {};
|
|
183
|
+
/**
|
|
184
|
+
* Decide whether `positional` runs a script; `undefined` means package mode.
|
|
185
|
+
* Throws {@link ScriptError} for a missing script, which must never fall
|
|
186
|
+
* through to a remote package download.
|
|
187
|
+
*/
|
|
188
|
+
function detectScript(positional, cwd) {
|
|
189
|
+
const [first] = positional;
|
|
190
|
+
if (first === void 0) return;
|
|
191
|
+
if (!first.startsWith("-")) return isScript(first, cwd) ? { nodeArgs: [...positional] } : void 0;
|
|
192
|
+
const nodeArgs = [];
|
|
193
|
+
let tsconfig;
|
|
194
|
+
let watch = false;
|
|
195
|
+
let entry = true;
|
|
196
|
+
for (let index = 0; index < positional.length; index++) {
|
|
197
|
+
const arg = positional[index];
|
|
198
|
+
if (arg === "--" || arg === "-" || !arg.startsWith("-")) {
|
|
199
|
+
const script = arg === "--" ? positional[index + 1] : arg;
|
|
200
|
+
if (script !== void 0 && entry) checkScriptAfterOptions(script, cwd);
|
|
201
|
+
nodeArgs.push(...positional.slice(index));
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
if (arg === "--tsconfig") {
|
|
205
|
+
if (positional[index + 1] === void 0) throw new ScriptError("--tsconfig requires a path");
|
|
206
|
+
tsconfig = positional[++index];
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (arg.startsWith("--tsconfig=")) {
|
|
210
|
+
tsconfig = arg.slice(11);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (arg === "--watch") {
|
|
214
|
+
watch = true;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const name = nodeOptionName(arg);
|
|
218
|
+
watch ||= name === "--watch-path";
|
|
219
|
+
entry &&= !NODE_OPTIONS_WITHOUT_ENTRY.has(name);
|
|
220
|
+
nodeArgs.push(arg);
|
|
221
|
+
const next = positional[index + 1];
|
|
222
|
+
if (!arg.includes("=") && next !== void 0 && takesNextArg(name, next)) nodeArgs.push(positional[++index]);
|
|
223
|
+
}
|
|
224
|
+
return watch ? {
|
|
225
|
+
nodeArgs,
|
|
226
|
+
tsconfig,
|
|
227
|
+
watch
|
|
228
|
+
} : {
|
|
229
|
+
nodeArgs,
|
|
230
|
+
tsconfig
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* After Node.js options, only a missing explicit path is an error. A bare name may be
|
|
235
|
+
* the value of an option missing from `NODE_OPTIONS_WITH_VALUE`, such as a coverage
|
|
236
|
+
* glob, and this position never falls back to a package, so Node.js reports a missing
|
|
237
|
+
* one itself.
|
|
238
|
+
*/
|
|
239
|
+
function checkScriptAfterOptions(token, cwd) {
|
|
240
|
+
if (isExplicitPath(token) && SCRIPT_EXTENSIONS.some((extension) => token.endsWith(extension)) && !isFile(path.resolve(cwd, token))) throw missingScript(token, path.resolve(cwd, token));
|
|
241
|
+
}
|
|
242
|
+
/** The error for a script path that is not a file. */
|
|
243
|
+
function missingScript(token, file) {
|
|
244
|
+
return new ScriptError(statSync(file, { throwIfNoEntry: false })?.isDirectory() ? `Script is a directory: ${token}` : `Script not found: ${token}`);
|
|
245
|
+
}
|
|
246
|
+
function isScript(token, cwd) {
|
|
247
|
+
const file = path.resolve(cwd, token);
|
|
248
|
+
const extension = SCRIPT_EXTENSIONS.find((candidate) => token.endsWith(candidate));
|
|
249
|
+
if (extension) {
|
|
250
|
+
if (isFile(file)) return true;
|
|
251
|
+
if (isExplicitPath(token) || TS_EXTENSIONS.has(extension)) throw missingScript(token, file);
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
if (!isExplicitPath(token)) return false;
|
|
255
|
+
const stats = statSync(file, { throwIfNoEntry: false });
|
|
256
|
+
if (!stats) throw new ScriptError(`Script not found: ${token}`);
|
|
257
|
+
return stats.isFile() && hasVpxShebang(file);
|
|
258
|
+
}
|
|
259
|
+
function isExplicitPath(token) {
|
|
260
|
+
if (token.startsWith("./") || token.startsWith("../") || token.startsWith("/")) return true;
|
|
261
|
+
return process.platform === "win32" && (token.startsWith(".\\") || token.startsWith("..\\") || /^(?:[a-zA-Z]:[\\/]|\\\\)/.test(token));
|
|
262
|
+
}
|
|
263
|
+
function isFile(file) {
|
|
264
|
+
return statSync(file, { throwIfNoEntry: false })?.isFile() ?? false;
|
|
265
|
+
}
|
|
266
|
+
/** The first `length` bytes of `file`, or none when it cannot be read. */
|
|
267
|
+
function readHead(file, length) {
|
|
268
|
+
const head = Buffer.alloc(length);
|
|
269
|
+
try {
|
|
270
|
+
const fd = openSync(file, "r");
|
|
271
|
+
try {
|
|
272
|
+
return head.subarray(0, readSync(fd, head, 0, length, 0));
|
|
273
|
+
} finally {
|
|
274
|
+
closeSync(fd);
|
|
275
|
+
}
|
|
276
|
+
} catch {
|
|
277
|
+
return head.subarray(0, 0);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function hasVpxShebang(file) {
|
|
281
|
+
const text = readHead(file, 256).toString("utf8");
|
|
282
|
+
if (!text.startsWith("#!")) return false;
|
|
283
|
+
return text.slice(2).split("\n", 1)[0].split(/\s+/).some((word) => {
|
|
284
|
+
const name = word.split(/[\\/]/).pop();
|
|
285
|
+
return name === "vpx" || name === "vpx.exe";
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/** The magic numbers of executables the kernel runs: Mach-O (thin and fat) on macOS, ELF elsewhere. */
|
|
289
|
+
const NATIVE_MAGIC = process.platform === "darwin" ? [
|
|
290
|
+
"feedface",
|
|
291
|
+
"feedfacf",
|
|
292
|
+
"cefaedfe",
|
|
293
|
+
"cffaedfe",
|
|
294
|
+
"cafebabe",
|
|
295
|
+
"bebafeca"
|
|
296
|
+
] : ["7f454c46"];
|
|
297
|
+
function isExecutableFile(file) {
|
|
298
|
+
try {
|
|
299
|
+
accessSync(file, constants.X_OK);
|
|
300
|
+
} catch {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
return isFile(file);
|
|
304
|
+
}
|
|
305
|
+
function isNativeExecutable(file) {
|
|
306
|
+
return isExecutableFile(file) && NATIVE_MAGIC.includes(readHead(file, 4).toString("hex"));
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Whether exec can run `file` itself: an executable native binary, or an executable
|
|
310
|
+
* script whose `#!` interpreter is one. A failed `process.execve()` aborts most supported
|
|
311
|
+
* Node.js versions instead of throwing, so the project-local bin runs anything else
|
|
312
|
+
* through `/bin/sh`, which reports a file it cannot run as a terminal does. The
|
|
313
|
+
* interpreter keeps a trailing `\r`, as the kernel reads it.
|
|
314
|
+
*/
|
|
315
|
+
function canExecDirectly(file) {
|
|
316
|
+
if (!isExecutableFile(file)) return false;
|
|
317
|
+
const head = readHead(file, 256);
|
|
318
|
+
if (head.subarray(0, 2).toString("latin1") !== "#!") return isNativeExecutable(file);
|
|
319
|
+
const interpreter = head.subarray(2).toString("utf8").split("\n", 1)[0].replace(/^[ \t]+/, "").split(/[ \t]/, 1)[0];
|
|
320
|
+
return path.isAbsolute(interpreter) && isNativeExecutable(interpreter);
|
|
321
|
+
}
|
|
322
|
+
/** Whether a package spec names a version, as in `eslint@9` or `@vue/cli@5`. */
|
|
323
|
+
function hasVersionSpec(spec) {
|
|
324
|
+
if (spec.startsWith("@")) {
|
|
325
|
+
const slash = spec.indexOf("/");
|
|
326
|
+
return slash !== -1 && spec.slice(slash + 1).includes("@");
|
|
327
|
+
}
|
|
328
|
+
return spec.includes("@");
|
|
329
|
+
}
|
|
330
|
+
/** The binary name a package spec runs: `eslint@9` → `eslint`, `@vue/cli@5` → `cli`. */
|
|
331
|
+
function commandName(spec) {
|
|
332
|
+
if (spec.startsWith("@")) {
|
|
333
|
+
const slash = spec.indexOf("/");
|
|
334
|
+
return slash === -1 ? spec : spec.slice(slash + 1).split("@")[0];
|
|
335
|
+
}
|
|
336
|
+
return spec.split("@")[0];
|
|
337
|
+
}
|
|
338
|
+
/** Every `node_modules/.bin` path from `cwd` up to the root, nearest first, whether or not it exists. */
|
|
339
|
+
function nodeModulesBinPaths(cwd) {
|
|
340
|
+
const paths = [];
|
|
341
|
+
for (let dir = cwd;; dir = path.dirname(dir)) {
|
|
342
|
+
paths.push(path.join(dir, "node_modules", ".bin"));
|
|
343
|
+
if (path.dirname(dir) === dir) return paths;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/** The nearest `node_modules/.bin/<name>` from `cwd` up (`.cmd` on Windows), like the global CLI's `find_local_binary`. */
|
|
347
|
+
function findLocalBin(name, cwd) {
|
|
348
|
+
const fileName = process.platform === "win32" ? `${name}.cmd` : name;
|
|
349
|
+
for (const dir of nodeModulesBinPaths(cwd)) {
|
|
350
|
+
const file = path.join(dir, fileName);
|
|
351
|
+
const stats = statSync(file, { throwIfNoEntry: false });
|
|
352
|
+
if (stats?.isFile()) return {
|
|
353
|
+
file,
|
|
354
|
+
stats
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/** An executable mode bit, as the global CLI checks; always true on Windows. */
|
|
359
|
+
function isExecutable(stats) {
|
|
360
|
+
return process.platform === "win32" || (stats.mode & 73) !== 0;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Package mode runs an explicit path as a program. An existing file must be executable,
|
|
364
|
+
* and a directory needs a package.json for `vp dlx`, so either fails here with a clear
|
|
365
|
+
* error instead of in `vp dlx`. Mirrors `check_explicit_program` in the global CLI.
|
|
366
|
+
*/
|
|
367
|
+
function checkExplicitProgram(token, cwd) {
|
|
368
|
+
if (!isExplicitPath(token)) return;
|
|
369
|
+
const file = path.resolve(cwd, token);
|
|
370
|
+
const stats = statSync(file, { throwIfNoEntry: false });
|
|
371
|
+
if (stats?.isDirectory() && !isFile(path.join(file, "package.json"))) return { error: `'${token}' is a directory without a package.json` };
|
|
372
|
+
if (stats?.isFile() && !isExecutable(stats)) return {
|
|
373
|
+
error: `'${token}' is not executable`,
|
|
374
|
+
note: `Make it executable with \`chmod +x ${token}\`.`
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* How the project-local bin runs `vpx <pkg> [args...]`. The nearest binary in
|
|
379
|
+
* `node_modules/.bin`, or an existing executable file, runs directly, as the global CLI
|
|
380
|
+
* execs the path it finds. A versioned package, `--package`, `--shell-mode`, or a local
|
|
381
|
+
* package directory runs with this package's `vp dlx`. Global packages and `PATH` are
|
|
382
|
+
* not searched, so a binary that is not installed is an error rather than a download.
|
|
383
|
+
*/
|
|
384
|
+
function packageInvocation(flags, [spec, ...rest], cwd) {
|
|
385
|
+
const silent = flags.silent ? ["--silent"] : [];
|
|
386
|
+
if (flags.packages.length > 0 || flags.shellMode || hasVersionSpec(spec)) return {
|
|
387
|
+
command: "dlx",
|
|
388
|
+
args: [
|
|
389
|
+
...flags.packages.flatMap((name) => ["--package", name]),
|
|
390
|
+
...flags.shellMode ? ["--shell-mode"] : [],
|
|
391
|
+
...silent,
|
|
392
|
+
spec,
|
|
393
|
+
...rest
|
|
394
|
+
]
|
|
395
|
+
};
|
|
396
|
+
if (isExplicitPath(spec)) {
|
|
397
|
+
const problem = checkExplicitProgram(spec, cwd);
|
|
398
|
+
if (problem) return problem;
|
|
399
|
+
const file = path.resolve(cwd, spec);
|
|
400
|
+
return isFile(file) ? {
|
|
401
|
+
command: "run",
|
|
402
|
+
file,
|
|
403
|
+
args: rest
|
|
404
|
+
} : {
|
|
405
|
+
command: "dlx",
|
|
406
|
+
args: [
|
|
407
|
+
...silent,
|
|
408
|
+
spec,
|
|
409
|
+
...rest
|
|
410
|
+
]
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const name = commandName(spec);
|
|
414
|
+
const bin = findLocalBin(name, cwd);
|
|
415
|
+
if (bin) {
|
|
416
|
+
if (!isExecutable(bin.stats)) {
|
|
417
|
+
const relative = path.relative(cwd, bin.file);
|
|
418
|
+
return {
|
|
419
|
+
error: `'${relative}' is not executable`,
|
|
420
|
+
note: `Reinstall dependencies with \`vp install\`, or make it executable with \`chmod +x ${relative}\`.`
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
command: "run",
|
|
425
|
+
file: bin.file,
|
|
426
|
+
args: rest
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
error: `'${name}' is not installed in node_modules`,
|
|
431
|
+
note: `Add it to devDependencies, or run \`vp dlx ${spec}\` to download and run it.`
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
export { canExecDirectly as a, nodeModulesBinPaths as c, WATCH_OPTIONS_WITH_VALUE as i, packageInvocation as l, SCRIPT_EXTENSIONS as n, detectScript as o, ScriptError as r, isFile as s, NODE_OPTIONS_WITH_VALUE as t, parseVpxArgs as u };
|
package/docs/config/run.md
CHANGED
|
@@ -56,6 +56,10 @@ export default defineConfig({
|
|
|
56
56
|
|
|
57
57
|
`cache: true` enables both task and script caching, `cache: false` disables both.
|
|
58
58
|
|
|
59
|
+
::: warning
|
|
60
|
+
This option can only be set in the workspace root's `vite.config.ts`. Setting it in a package's config will result in an error.
|
|
61
|
+
:::
|
|
62
|
+
|
|
59
63
|
## `run.tasks`
|
|
60
64
|
|
|
61
65
|
- **Type:** `Record<string, Task | string | string[]>`
|
package/docs/guide/check.md
CHANGED
|
@@ -16,6 +16,7 @@ We recommend turning both `typeAware` and `typeCheck` on so `vp check` becomes t
|
|
|
16
16
|
vp check
|
|
17
17
|
vp check --fix # Format and run autofixers.
|
|
18
18
|
vp check --quiet # Hide lint warnings; still report and fail on errors.
|
|
19
|
+
vp check --deny-warnings # Treat lint warnings as errors.
|
|
19
20
|
vp check --no-fmt # Skip format; run lint (and type-check if enabled).
|
|
20
21
|
vp check --no-lint # Skip lint rules; keep type-check when enabled.
|
|
21
22
|
vp check --no-fmt --no-lint # Type-check only (requires both `typeAware` and `typeCheck` enabled).
|
package/docs/guide/ci.md
CHANGED
|
@@ -4,7 +4,7 @@ You can use `voidzero-dev/setup-vp` to use Vite+ in CI environments.
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
[`voidzero-dev/setup-vp`](https://github.com/voidzero-dev/setup-vp) provides integrations for GitHub Actions, GitLab CI/CD, and Azure Pipelines. All three install Vite
|
|
7
|
+
[`voidzero-dev/setup-vp`](https://github.com/voidzero-dev/setup-vp) provides integrations for GitHub Actions, GitLab CI/CD, and Azure Pipelines. All three install Vite+, can select the project's Node.js version, and can install project dependencies. The GitHub Action and Azure Pipelines template can also cache package-manager data automatically. GitLab CI/CD uses the job's native cache configuration and requires Node.js to start the setup runtime.
|
|
8
8
|
|
|
9
9
|
## setup-vp Versioning
|
|
10
10
|
|
|
@@ -12,6 +12,16 @@ Set `<setup-vp-version>` in each example to an exact version from the [`setup-vp
|
|
|
12
12
|
|
|
13
13
|
Run `vp migrate` to replace exact `voidzero-dev/setup-vp@v1` references in GitHub Actions workflows and composite actions under `.github` with the latest exact release known to your Vite+ version. Existing exact versions and commit SHAs remain unchanged.
|
|
14
14
|
|
|
15
|
+
## Node.js During Installation
|
|
16
|
+
|
|
17
|
+
The Vite+ installer uses the latest Node.js LTS by default. With versions that support [`VP_SETUP_NODE_VERSION`](/guide/global-cli#vp-setup-node-version), `setup-vp` can use the project's version for installation too. This avoids a second Node.js download when that version supports both the global CLI and its pinned `pnpm`.
|
|
18
|
+
|
|
19
|
+
`setup-vp` selects the version before it starts the installer. An explicit Node.js version takes precedence over a version-file input. Without either input, it checks the working directory and its parents using the [project declaration order](/guide/env#node-js-selection). The integration passes the selection through `VP_SETUP_NODE_VERSION`; the installer itself does not read project declarations.
|
|
20
|
+
|
|
21
|
+
Without a selection, with Node.js management disabled, or when the selected version is incompatible, installation uses LTS. Older installers keep their existing behavior. Automatic project discovery does not create a session override, so later commands retain normal directory-based version selection.
|
|
22
|
+
|
|
23
|
+
The integration handles these installer variables automatically. Configure `node-version` or `node-version-file` in GitHub Actions and GitLab CI/CD, or `nodeVersion` or `nodeVersionFile` in Azure Pipelines. See the [`setup-vp` documentation](https://github.com/voidzero-dev/setup-vp#inputs) for the complete input reference.
|
|
24
|
+
|
|
15
25
|
## GitHub Actions
|
|
16
26
|
|
|
17
27
|
The GitHub Action sets up Vite+, the required Node.js version, and the package manager. This means you usually do not need separate `setup-node`, package-manager setup, dependency installation, or manual dependency caching steps in your workflow.
|
|
@@ -53,7 +63,7 @@ test:
|
|
|
53
63
|
|
|
54
64
|
The GitLab CI/CD integration differs from the GitHub Action in a few ways:
|
|
55
65
|
|
|
56
|
-
- The template
|
|
66
|
+
- The template requires Node.js to start the setup runtime. Use a Node.js image, as shown above, or otherwise provide Node.js in the job. Use `node-version` or `node-version-file` to select a managed project runtime with `vp env use`.
|
|
57
67
|
- Configure dependency caching with the job's GitLab [`cache`](https://docs.gitlab.com/ci/yaml/#cache) keyword.
|
|
58
68
|
- Use a Unix-like runner environment with Bash and either `curl` or `wget`.
|
|
59
69
|
|
|
@@ -90,7 +100,7 @@ steps:
|
|
|
90
100
|
|
|
91
101
|
Pin `ref` and `setupRef` to the same tag or commit SHA for strict reproducibility.
|
|
92
102
|
|
|
93
|
-
The Azure Pipelines template supports Microsoft-hosted Linux, macOS, and Windows agents.
|
|
103
|
+
The Azure Pipelines template supports Microsoft-hosted Linux, macOS, and Windows agents. `UseNode@1` provides Node.js to start the setup runtime through `bootstrapNodeVersion`. The `nodeVersion` and `nodeVersionFile` parameters select the managed project runtime with `vp env use`. `Cache@2` caches package-manager data.
|
|
94
104
|
|
|
95
105
|
For advanced configuration and the complete parameter reference, see the [`setup-vp` Azure Pipelines documentation](https://github.com/voidzero-dev/setup-vp#azure-pipelines).
|
|
96
106
|
|
package/docs/guide/create.md
CHANGED
|
@@ -20,6 +20,40 @@ vp create <template>
|
|
|
20
20
|
vp create <template> -- <template-options>
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
### Without the Global CLI
|
|
24
|
+
|
|
25
|
+
If you haven't installed [the global `vp`](/guide/global-cli) yet. Vite+ provides `create-vite-plus` package running `vp create` through your package manager.
|
|
26
|
+
|
|
27
|
+
::: code-group
|
|
28
|
+
|
|
29
|
+
```bash [pnpm]
|
|
30
|
+
pnpm create vite-plus
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash [npm]
|
|
34
|
+
npm create vite-plus@latest
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```bash [Yarn]
|
|
38
|
+
yarn create vite-plus
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```bash [Bun]
|
|
42
|
+
bun create vite-plus
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
:::
|
|
46
|
+
|
|
47
|
+
The new project uses the package manager that ran the command, unless you pass `--package-manager` or create it inside an existing workspace. Arguments are forwarded to `vp create` unchanged, so the first argument is the template, not the target directory:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm create vite-plus vite:application --directory my-app
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If you are using npm, there is a `--` needed before options meant for `vp create`, for example `npm create vite-plus@latest -- vite:application --directory my-app`.
|
|
54
|
+
|
|
55
|
+
After creating the project, run `vp` through your package manager, for example `pnpm exec vp run`.
|
|
56
|
+
|
|
23
57
|
## Built-in Templates
|
|
24
58
|
|
|
25
59
|
Vite+ ships with these built-in templates:
|
package/docs/guide/env.md
CHANGED
|
@@ -41,18 +41,23 @@ To select the project's Node.js version, Vite+ checks the current directory firs
|
|
|
41
41
|
|
|
42
42
|
If no directory declares a version, Vite+ uses the global default (`vp env default`) and then the latest LTS.
|
|
43
43
|
|
|
44
|
+
These rules select Node.js for project commands. The installer uses the latest LTS by default. Only [`VP_SETUP_NODE_VERSION`](/guide/global-cli#vp-setup-node-version) changes its dependency-installation runtime; [`setup-vp`](/guide/ci#node-js-during-installation) supplies this override from the CI inputs or project declarations.
|
|
45
|
+
|
|
44
46
|
`devEngines.runtime` ranks above `engines.node` because it declares the development-environment requirement, while `engines.node` is a consumer-facing support range. `vp env doctor` warns when declared sources conflict.
|
|
45
47
|
|
|
46
48
|
::: tip Using pnpm with Vite+ runtime management
|
|
47
49
|
pnpm can also manage the runtime declared in `devEngines.runtime`. When both pnpm and Vite+ manage Node.js, they can download the same version separately or select different versions, causing inconsistent behavior between commands.
|
|
48
50
|
|
|
49
|
-
If
|
|
51
|
+
If your project uses Vite+ to manage Node.js and pnpm versions, add these settings to the project's `pnpm-workspace.yaml` (pnpm 11+):
|
|
50
52
|
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
+
```yaml
|
|
54
|
+
runtimeOnFail: ignore
|
|
55
|
+
pmOnFail: ignore
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
[`runtimeOnFail`](https://pnpm.io/settings/cli#runtimeonfail) disables pnpm's automatic management of declared runtimes. [`pmOnFail`](https://pnpm.io/settings/cli#pmonfail) prevents pnpm from switching to the package-manager version declared in `package.json`. Commit these settings so the project shares the same policy.
|
|
59
|
+
|
|
60
|
+
`runtimeOnFail: ignore` also affects other declared runtimes, including Bun and Deno. If the project relies on pnpm to manage them, consider that before enabling this setting. Switching an existing project to this policy can change runtime entries in `pnpm-lock.yaml` on the next install; review and commit those changes with the configuration.
|
|
56
61
|
:::
|
|
57
62
|
|
|
58
63
|
## Package-Manager Selection
|
|
@@ -76,7 +81,7 @@ Package-manager selection uses this priority:
|
|
|
76
81
|
| `VP_YARN_VERSION` | `yarn`, `yarnpkg` |
|
|
77
82
|
| `VP_BUN_VERSION` | `bun`, `bunx` |
|
|
78
83
|
|
|
79
|
-
These variables accept a version or
|
|
84
|
+
These variables accept a version, range, or npm dist-tag, such as `10.18.0`, `10`, `latest`, or `latest-10`, and override the matching shim's project and default versions. They do not change the manager or version selected by `vp install`.
|
|
80
85
|
|
|
81
86
|
`vp env use pnpm@10.20.0` sets `VP_PNPM_VERSION` for the current shell, just as `vp env use node@22` sets `VP_NODE_VERSION`. Each package manager has its own override, so switching Yarn does not clear a pnpm override. `vp env use` does not set or clear `VP_PACKAGE_MANAGER`.
|
|
82
87
|
|
|
@@ -87,12 +92,14 @@ VP_PACKAGE_MANAGER=pnpm@10.18.0 vp install
|
|
|
87
92
|
VP_PNPM_VERSION=10.20.0 pnpm --version
|
|
88
93
|
```
|
|
89
94
|
|
|
90
|
-
The overrides apply in managed mode. A package manager can also perform its own version switching after Vite+ launches it; for example, pnpm's `
|
|
95
|
+
The overrides apply in managed mode. A package manager can also perform its own version switching after Vite+ launches it; for example, pnpm 11+'s [`pmOnFail`](https://pnpm.io/settings/cli#pmonfail) defaults to `download` and may switch back to the version in `package.json`. To let Vite+ control the pnpm version, set `pmOnFail: ignore` in the project's `pnpm-workspace.yaml`. In pnpm 10, the corresponding setting is `managePackageManagerVersions`.
|
|
91
96
|
|
|
92
97
|
A project selection applies only to its matching shims. For example, pnpm controls `pnpm`, `pnpx`, `pn`, and `pnx`; invoking `npm` still resolves npm independently. Without a matching project selection, a named shim uses its configured default version and otherwise uses the latest release without prompting. The npm shim falls back to Node's bundled npm. `vp env use npm` selects standalone npm's latest release for the current shell when no project version or global default is configured.
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
Package-manager specs follow npm's order: an exact version, then a semver range, then a dist-tag. `default` is an alias of `latest`, except for npm, where it selects the npm on `PATH`.
|
|
100
|
+
|
|
101
|
+
::: details Dist-tag caching
|
|
102
|
+
When a package-manager dist-tag such as `latest` or `latest-10` is resolved, including a named shim falling back to the latest release, the resolved version is cached for one hour. An expired cache remains available when the registry cannot be reached.
|
|
96
103
|
:::
|
|
97
104
|
|
|
98
105
|
`pn` runs the same managed binary as `pnpm`, and `pnx` runs the same managed binary as `pnpx` (`pnpm dlx`). These aliases also work with managed pnpm versions older than v11.
|
|
@@ -176,20 +183,25 @@ In CI, `vp env use` can run without shell initialization. It writes a temporary
|
|
|
176
183
|
The global CLI supports Tab completion in Bash, Zsh, Fish, Nushell, and PowerShell. Run `vp env setup` and follow its printed shell setup instructions to enable it. Press Tab to complete commands, or project task names after `vp run` and `vpr`.
|
|
177
184
|
|
|
178
185
|
- **Zsh**: Run `autoload -Uz compinit; compinit` before loading the setup script if your shell has not initialized completion.
|
|
179
|
-
- **Nushell**: Completion requires `fish` on `PATH`.
|
|
186
|
+
- **Nushell**: Completion requires `fish` on `PATH`. Use Nushell 0.112.1 or later; see [Nushell version](/guide/global-cli#nushell-version).
|
|
180
187
|
|
|
181
188
|
### Manage
|
|
182
189
|
|
|
183
190
|
- `vp env default` shows the global Node.js default and each configured package-manager version. Bare versions set Node.js; qualified specs such as `pnpm@10.18.0` set that package manager's shim default without replacing the defaults for Bun, Yarn, or npm. `--unset` clears all defaults unless scoped.
|
|
184
|
-
- `vp env default <lts|latest>` and
|
|
185
|
-
- `vp env pin` shows or writes project pins.
|
|
186
|
-
|
|
191
|
+
- `vp env default <lts|latest>` and package-manager dist-tags such as `pnpm@latest` or `pnpm@latest-10` re-resolve on each use, so the default follows the tag, including new majors for `latest`. Other versions and ranges, such as `24` or `pnpm@10`, resolve to an exact version when set.
|
|
192
|
+
- `vp env pin` shows or writes project pins. Node.js pins use the current directory. Package-manager pins use the workspace root `package.json`, or the current project `package.json` outside a workspace. Pinning both components can update two different files.
|
|
193
|
+
|
|
194
|
+
Existing `.node-version` and top-level `packageManager` fields keep being updated for compatibility. An existing `.nvmrc` is updated when it is the effective Node source in the current directory. Its comments and other non-version content are preserved. Otherwise Vite+ writes the matching `devEngines` entry.
|
|
195
|
+
|
|
196
|
+
Use `--target node-version`, `--target nvmrc`, `--target dev-engines`, or `--target package-manager` to choose the pin source explicitly. This does not change the project directory. Package-manager output shows the file path relative to the current working directory and the field that was updated, or the target before an existing overwrite prompt. Pinning in a child directory does not modify an inherited `.nvmrc`.
|
|
197
|
+
|
|
198
|
+
- `vp env unpin` (alias for `vp env pin --unpin`) removes both effective pins by default. Append a selector to remove one. Node.js removal uses the current directory. Package-manager removal uses the workspace root manifest, or the current project manifest outside a workspace. `--target` selects the pin source within that scope. The output identifies the removed package-manager field, or the fields checked when no matching pin is found. Lower-priority declarations are not deleted.
|
|
187
199
|
- `vp env use` activates the complete project environment. Explicit specs override selected components; `--unset` clears both unless scoped.
|
|
188
200
|
- `vp env install` installs the complete resolved environment, a selected component, or explicit specs.
|
|
189
201
|
- `vp env uninstall` removes the Node.js version resolved from an explicit version or selector, such as `22` or `lts`. Package managers require a qualified exact version, such as `pnpm@10.18.0`.
|
|
190
202
|
- `vp env clean` removes unused installs. Use `clean node`, `clean pm`, or a concrete manager. Current and configured-default versions are preserved.
|
|
191
203
|
- `vp env exec` runs a command in the resolved environment. Use `--node` and `--package-manager`; `--npm` is an alias for `--package-manager npm@…`.
|
|
192
|
-
- `vp node` uses the resolved Node.js runtime and exposes the selected package-manager path to child processes.
|
|
204
|
+
- `vp node` uses the resolved Node.js runtime and exposes the selected package-manager path to child processes. It runs Node.js as is, so TypeScript files get Node.js type stripping only; [`vpx <file>`](/guide/vpx#running-scripts) runs them on the same runtime with full TypeScript support.
|
|
193
205
|
|
|
194
206
|
### Inspect
|
|
195
207
|
|
|
@@ -217,7 +229,9 @@ vp env print # Print PATH setup for both components
|
|
|
217
229
|
|
|
218
230
|
# Manage
|
|
219
231
|
vp env pin lts # Pin Node.js only to an exact version
|
|
232
|
+
vp env pin node@26 # Pin Node.js 26 to an exact version
|
|
220
233
|
vp env pin lts pnpm@10 # Pin both project components to exact versions
|
|
234
|
+
vp env pin pnpm@latest-10 # Pin pnpm to the version of its latest-10 dist-tag
|
|
221
235
|
vp env install # Install the complete resolved environment
|
|
222
236
|
vp env use 20 pnpm@10 # Override both components for this shell
|
|
223
237
|
vp env use --unset pnpm # Remove only the pnpm session version
|