vite-plus 0.1.24 → 0.2.1

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.
Files changed (174) hide show
  1. package/LICENSE +30 -0
  2. package/README.md +8 -6
  3. package/bin/oxfmt +5 -2
  4. package/bin/oxlint +12 -2
  5. package/binding/index.cjs +84 -67
  6. package/binding/index.d.cts +155 -4
  7. package/dist/{agent-Nuk-9l77.js → agent--cKmgD_n.js} +941 -70
  8. package/dist/bin.js +22 -30
  9. package/dist/{compat-DXZgnEyq.js → compat-Cql3K40m.js} +1 -1
  10. package/dist/config/bin.js +30 -14
  11. package/dist/constants-CrfJQIUX.js +66 -0
  12. package/dist/create/bin.d.ts +6 -0
  13. package/dist/create/bin.js +508 -232
  14. package/dist/define-config-2tfJoXr1.d.ts +305 -0
  15. package/dist/define-config-BGSjF6Xp.cjs +488 -0
  16. package/dist/define-config-DJUehepE.js +445 -0
  17. package/dist/define-config.cjs +8 -1
  18. package/dist/define-config.d.ts +2 -2
  19. package/dist/define-config.js +2 -2
  20. package/dist/dist-DRJUd9bL.js +3 -0
  21. package/dist/{dist-BgQuvbtq.js → dist-Oxo16Y0q.js} +4 -4
  22. package/dist/index.cjs +9 -4
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +3 -3
  25. package/dist/{main-DpJl3LoU.js → json-Dn87fvjk.js} +137 -1
  26. package/dist/migration/bin.js +292 -76
  27. package/dist/{oxlint-plugin-config-B89iKTKN.js → oxlint-plugin-config-q8a5PFch.js} +1 -1
  28. package/dist/oxlint-plugin.js +11 -3
  29. package/dist/pack-bin.js +44 -15
  30. package/dist/{package-PmBUZ-ve.js → package-BHirM1_v.js} +3 -138
  31. package/dist/{report-DgSBQUdz.js → report-BHSkWqRR.js} +2 -0
  32. package/dist/{resolve-vite-config-TTvhycU1.js → resolve-vite-config-CmdsfQzS.js} +13 -4
  33. package/dist/staged/bin.js +5 -5
  34. package/dist/test/_at-vitest-browser/context.d.ts +2 -0
  35. package/dist/test/_at-vitest-browser.d.ts +2 -0
  36. package/dist/test/browser/context.d.ts +2 -2
  37. package/dist/test/browser/context.js +1 -1
  38. package/dist/test/browser/providers/playwright/context.d.ts +1 -0
  39. package/dist/test/browser/providers/playwright/context.js +1 -0
  40. package/dist/test/browser/providers/playwright.d.ts +124 -2
  41. package/dist/test/browser/providers/playwright.js +1 -1
  42. package/dist/test/browser/providers/preview/context.d.ts +1 -0
  43. package/dist/test/browser/providers/preview/context.js +1 -0
  44. package/dist/test/browser/providers/preview.d.ts +32 -2
  45. package/dist/test/browser/providers/preview.js +1 -1
  46. package/dist/test/browser/providers/webdriverio/context.d.ts +1 -0
  47. package/dist/test/browser/providers/webdriverio/context.js +1 -0
  48. package/dist/test/browser/providers/webdriverio.d.ts +77 -2
  49. package/dist/test/browser/providers/webdriverio.js +1 -1
  50. package/dist/test/browser-compat.d.ts +2 -0
  51. package/dist/test/browser-compat.js +1 -1
  52. package/dist/test/browser-playwright/context.d.ts +1 -0
  53. package/dist/test/browser-playwright/context.js +1 -0
  54. package/dist/test/browser-playwright.d.ts +124 -2
  55. package/dist/test/browser-playwright.js +1 -1
  56. package/dist/test/browser-preview/context.d.ts +1 -0
  57. package/dist/test/browser-preview/context.js +1 -0
  58. package/dist/test/browser-preview.d.ts +32 -2
  59. package/dist/test/browser-preview.js +1 -1
  60. package/dist/test/browser-webdriverio/context.d.ts +1 -0
  61. package/dist/test/browser-webdriverio/context.js +1 -0
  62. package/dist/test/browser-webdriverio.d.ts +77 -2
  63. package/dist/test/browser-webdriverio.js +1 -1
  64. package/dist/test/browser.d.ts +2 -2
  65. package/dist/test/browser.js +1 -1
  66. package/dist/test/client.js +1 -1
  67. package/dist/test/config.cjs +1 -1
  68. package/dist/test/config.d.ts +2 -2
  69. package/dist/test/config.js +1 -1
  70. package/dist/test/context.d.ts +942 -2
  71. package/dist/test/context.js +1 -1
  72. package/dist/test/coverage.d.ts +2 -2
  73. package/dist/test/coverage.js +1 -1
  74. package/dist/test/environments.d.ts +2 -2
  75. package/dist/test/environments.js +1 -1
  76. package/dist/test/globals.d.ts +2 -2
  77. package/dist/test/import-meta.d.ts +2 -2
  78. package/dist/test/importMeta.d.ts +2 -2
  79. package/dist/test/index.cjs +1 -1
  80. package/dist/test/index.d.cts +2 -2
  81. package/dist/test/index.d.ts +2 -2
  82. package/dist/test/index.js +1 -1
  83. package/dist/test/internal/browser.d.ts +2 -2
  84. package/dist/test/internal/browser.js +1 -1
  85. package/dist/test/jsdom.d.ts +2 -2
  86. package/dist/test/locators.d.ts +294 -0
  87. package/dist/test/locators.js +1 -1
  88. package/dist/test/matchers.d.ts +29 -0
  89. package/dist/test/matchers.js +1 -1
  90. package/dist/test/node.d.ts +2 -2
  91. package/dist/test/node.js +1 -1
  92. package/dist/test/optional-runtime-types.js.d.ts +2 -2
  93. package/dist/test/optional-types.js.d.ts +2 -2
  94. package/dist/test/plugins/browser-client.js +1 -1
  95. package/dist/test/plugins/browser-context.js +1 -1
  96. package/dist/test/plugins/browser-locators.js +1 -1
  97. package/dist/test/plugins/browser-playwright.js +1 -1
  98. package/dist/test/plugins/browser-preview.js +1 -1
  99. package/dist/test/plugins/browser-webdriverio.js +1 -1
  100. package/dist/test/plugins/browser.js +1 -1
  101. package/dist/test/plugins/expect.js +1 -1
  102. package/dist/test/plugins/mocker-automock.js +1 -1
  103. package/dist/test/plugins/mocker-browser.js +1 -1
  104. package/dist/test/plugins/mocker-node.js +1 -1
  105. package/dist/test/plugins/mocker-redirect.js +1 -1
  106. package/dist/test/plugins/mocker-register.js +1 -1
  107. package/dist/test/plugins/mocker-transforms.js +1 -1
  108. package/dist/test/plugins/mocker.js +1 -1
  109. package/dist/test/plugins/pretty-format.js +1 -1
  110. package/dist/test/plugins/runner-types.js +1 -1
  111. package/dist/test/plugins/runner-utils.js +1 -1
  112. package/dist/test/plugins/runner.js +1 -1
  113. package/dist/test/plugins/snapshot-environment.js +1 -1
  114. package/dist/test/plugins/snapshot-manager.js +1 -1
  115. package/dist/test/plugins/snapshot.js +1 -1
  116. package/dist/test/plugins/spy.js +1 -1
  117. package/dist/test/plugins/utils-constants.js +1 -1
  118. package/dist/test/plugins/utils-diff.js +1 -1
  119. package/dist/test/plugins/utils-display.js +1 -1
  120. package/dist/test/plugins/utils-error.js +1 -1
  121. package/dist/test/plugins/utils-helpers.js +1 -1
  122. package/dist/test/plugins/utils-offset.js +1 -1
  123. package/dist/test/plugins/utils-resolver.js +1 -1
  124. package/dist/test/plugins/utils-serialize.js +1 -1
  125. package/dist/test/plugins/utils-source-map-node.js +1 -1
  126. package/dist/test/plugins/utils-source-map.js +1 -1
  127. package/dist/test/plugins/utils-timers.js +1 -1
  128. package/dist/test/plugins/utils.js +1 -1
  129. package/dist/test/reporters.d.ts +2 -2
  130. package/dist/test/reporters.js +1 -1
  131. package/dist/test/runners.d.ts +2 -2
  132. package/dist/test/runners.js +1 -1
  133. package/dist/test/runtime.d.ts +2 -2
  134. package/dist/test/runtime.js +1 -1
  135. package/dist/test/snapshot.d.ts +2 -2
  136. package/dist/test/snapshot.js +1 -1
  137. package/dist/test/suite.d.ts +2 -2
  138. package/dist/test/suite.js +1 -1
  139. package/dist/test/utils.js +1 -1
  140. package/dist/test/worker.d.ts +2 -2
  141. package/dist/test/worker.js +1 -1
  142. package/dist/{tsconfig-DFb5BKyT.js → tsconfig-BWQPmGKz.js} +565 -231
  143. package/dist/tsgolint-path-B-yOos8p.js +32 -0
  144. package/dist/tsgolint-path.d.ts +8 -0
  145. package/dist/tsgolint-path.js +2 -0
  146. package/dist/version.js +3 -3
  147. package/dist/versions.d.ts +1 -1
  148. package/dist/versions.js +6 -6
  149. package/dist/{workspace-NL-m9wgM.js → workspace-D0AVy4fu.js} +11 -9
  150. package/docs/_data/team.ts +2 -1
  151. package/docs/config/create.md +36 -1
  152. package/docs/config/index.md +7 -5
  153. package/docs/guide/commit-hooks.md +9 -0
  154. package/docs/guide/create.md +106 -2
  155. package/docs/guide/env.md +33 -5
  156. package/docs/guide/index.md +5 -3
  157. package/docs/guide/install.md +31 -12
  158. package/docs/guide/migrate.md +13 -3
  159. package/docs/guide/troubleshooting.md +2 -2
  160. package/docs/guide/upgrade.md +26 -7
  161. package/docs/package.json +3 -3
  162. package/docs/pnpm-lock.yaml +298 -395
  163. package/package.json +103 -55
  164. package/templates/generator/bin/index.ts +6 -3
  165. package/templates/generator/package.json +2 -3
  166. package/templates/generator/src/template.ts +0 -2
  167. package/templates/monorepo/package.json +1 -1
  168. package/dist/constants-DCBWlNrn.js +0 -33
  169. package/dist/define-config-BR1Y88zz.cjs +0 -84
  170. package/dist/define-config-BRC7qPNE.js +0 -21
  171. package/dist/define-config-COdn-tsn.d.ts +0 -177
  172. package/dist/dist-Bapm49IR.js +0 -3
  173. package/dist/test/plugins/utils-highlight.js +0 -1
  174. /package/dist/{chunk-DnnnRqeS.js → rolldown-runtime-DnnnRqeS.js} +0 -0
@@ -0,0 +1,32 @@
1
+ import { dirname, join } from "node:path";
2
+ import { existsSync, realpathSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ //#region src/utils/tsgolint-path.ts
5
+ function resolveWindowsTsgolintExecutable(pathCandidates, options) {
6
+ let oxlintTsgolintPath = pathCandidates.find((p) => options.exists(p)) ?? "";
7
+ if (!oxlintTsgolintPath && options.getRealpathCandidates) try {
8
+ oxlintTsgolintPath = options.getRealpathCandidates().find((p) => options.exists(p)) ?? "";
9
+ } catch {}
10
+ if (!oxlintTsgolintPath) throw new Error("Unable to resolve oxlint-tsgolint executable, tried:\n" + pathCandidates.map((path) => `- ${path}`).join("\n"));
11
+ return oxlintTsgolintPath;
12
+ }
13
+ function resolveTsgolintExecutable(tsgolintBinPath, scriptUrl) {
14
+ if (process.platform !== "win32") return tsgolintBinPath;
15
+ const scriptDir = dirname(fileURLToPath(scriptUrl));
16
+ const localBinDir = join(scriptDir, "..", "node_modules", ".bin");
17
+ const projectBinDir = join(dirname(dirname(tsgolintBinPath)), "..", ".bin");
18
+ return resolveWindowsTsgolintExecutable([
19
+ join(localBinDir, "tsgolint.exe"),
20
+ join(localBinDir, "tsgolint.cmd"),
21
+ join(projectBinDir, "tsgolint.exe"),
22
+ join(projectBinDir, "tsgolint.cmd")
23
+ ], {
24
+ exists: existsSync,
25
+ getRealpathCandidates: () => {
26
+ const realBinDir = join(dirname(realpathSync(join(scriptDir, ".."))), ".bin");
27
+ return [join(realBinDir, "tsgolint.exe"), join(realBinDir, "tsgolint.cmd")];
28
+ }
29
+ });
30
+ }
31
+ //#endregion
32
+ export { resolveWindowsTsgolintExecutable as n, resolveTsgolintExecutable as t };
@@ -0,0 +1,8 @@
1
+ //#region src/utils/tsgolint-path.d.ts
2
+ declare function resolveWindowsTsgolintExecutable(pathCandidates: string[], options: {
3
+ exists: (path: string) => boolean;
4
+ getRealpathCandidates?: () => string[];
5
+ }): string;
6
+ declare function resolveTsgolintExecutable(tsgolintBinPath: string, scriptUrl: string): string;
7
+ //#endregion
8
+ export { resolveTsgolintExecutable, resolveWindowsTsgolintExecutable };
@@ -0,0 +1,2 @@
1
+ import { n as resolveWindowsTsgolintExecutable, t as resolveTsgolintExecutable } from "./tsgolint-path-B-yOos8p.js";
2
+ export { resolveTsgolintExecutable, resolveWindowsTsgolintExecutable };
package/dist/version.js CHANGED
@@ -1,11 +1,11 @@
1
- import "./constants-DCBWlNrn.js";
1
+ import "./constants-CrfJQIUX.js";
2
2
  import { a as printHeader, r as log, t as accent } from "./terminal-uTv0ZaMr.js";
3
- import { i as hasVitePlusDependency, n as detectPackageMetadata } from "./package-PmBUZ-ve.js";
3
+ import { i as hasVitePlusDependency, n as detectPackageMetadata } from "./package-BHirM1_v.js";
4
4
  import { t as renderCliDoc } from "./help-YP84FSEz.js";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs";
7
7
  //#region package.json
8
- var version = "0.1.24";
8
+ var version = "0.2.1";
9
9
  //#endregion
10
10
  //#region src/version.ts
11
11
  /** Tool display names in the order shown by `vp --version`. */
@@ -2,8 +2,8 @@ export declare const versions: {
2
2
  readonly 'vite': string;
3
3
  readonly 'rolldown': string;
4
4
  readonly 'tsdown': string;
5
- readonly 'vitest': string;
6
5
  readonly 'oxlint': string;
7
6
  readonly 'oxfmt': string;
8
7
  readonly 'oxlint-tsgolint': string;
8
+ readonly 'vitest': string;
9
9
  };
package/dist/versions.js CHANGED
@@ -1,9 +1,9 @@
1
1
  export const versions = {
2
2
  "vite": "8.0.16",
3
- "rolldown": "1.0.3",
4
- "tsdown": "0.22.1",
5
- "vitest": "4.1.8",
6
- "oxlint": "1.67.0",
7
- "oxfmt": "0.52.0",
8
- "oxlint-tsgolint": "0.23.0"
3
+ "rolldown": "1.1.1",
4
+ "tsdown": "0.22.3",
5
+ "oxlint": "1.70.0",
6
+ "oxfmt": "0.55.0",
7
+ "oxlint-tsgolint": "0.23.0",
8
+ "vitest": "4.1.9"
9
9
  };
@@ -1,7 +1,8 @@
1
- import { A as R$1, C as log, E as select, v as PackageManager, w as multiselect } from "./tsconfig-DFb5BKyT.js";
2
- import { t as require_dist } from "./dist-BgQuvbtq.js";
3
- import { c as editJsonFile, d as writeJsonFile, r as getScopeFromPackageName, u as readJsonFile } from "./package-PmBUZ-ve.js";
4
- import { B as editYamlFile, V as readYamlFile } from "./agent-Nuk-9l77.js";
1
+ import { A as select, D as log, O as multiselect, P as R$1, S as PackageManager } from "./tsconfig-BWQPmGKz.js";
2
+ import { i as writeJsonFile, r as readJsonFile, t as editJsonFile } from "./json-Dn87fvjk.js";
3
+ import { t as require_dist } from "./dist-Oxo16Y0q.js";
4
+ import { r as getScopeFromPackageName } from "./package-BHirM1_v.js";
5
+ import { G as editYamlFile, K as readYamlFile } from "./agent--cKmgD_n.js";
5
6
  import path, { posix, win32 } from "node:path";
6
7
  import { detectWorkspace } from "../binding/index.js";
7
8
  import * as actualFS from "node:fs";
@@ -5779,6 +5780,9 @@ async function detectWorkspace$1(rootDir) {
5779
5780
  }
5780
5781
  return result;
5781
5782
  }
5783
+ function isBingoTemplate(pkg) {
5784
+ return !!pkg.dependencies?.bingo;
5785
+ }
5782
5786
  function discoverWorkspacePackages(workspacePatterns, rootDir) {
5783
5787
  const packages = [];
5784
5788
  if (workspacePatterns.length === 0) return packages;
@@ -5790,13 +5794,11 @@ function discoverWorkspacePackages(workspacePatterns, rootDir) {
5790
5794
  for (const packageJsonRelativePath of packageJsonRelativePaths) {
5791
5795
  const pkg = readJsonFile(path.join(rootDir, packageJsonRelativePath));
5792
5796
  if (!pkg.name) continue;
5793
- const isTemplatePackage = pkg.keywords?.includes("vite-plus-template") || pkg.keywords?.includes("bingo-template") || !!pkg.dependencies?.bingo;
5794
5797
  packages.push({
5795
5798
  name: pkg.name,
5796
- path: path.dirname(packageJsonRelativePath),
5799
+ path: path.dirname(packageJsonRelativePath).split(path.sep).join("/"),
5797
5800
  description: pkg.description,
5798
- version: pkg.version,
5799
- isTemplatePackage
5801
+ version: pkg.version
5800
5802
  });
5801
5803
  }
5802
5804
  return packages;
@@ -5825,4 +5827,4 @@ function updateWorkspaceConfig(projectPath, workspaceInfo) {
5825
5827
  });
5826
5828
  }
5827
5829
  //#endregion
5828
- export { detectExistingEditors as a, writeEditorConfigs as c, detectEditorConflicts as i, updatePackageJsonWithDeps as n, selectEditor as o, updateWorkspaceConfig as r, selectEditors as s, detectWorkspace$1 as t };
5830
+ export { detectEditorConflicts as a, selectEditors as c, updateWorkspaceConfig as i, writeEditorConfigs as l, isBingoTemplate as n, detectExistingEditors as o, updatePackageJsonWithDeps as r, selectEditor as s, detectWorkspace$1 as t };
@@ -30,7 +30,7 @@ export const core: DefaultTheme.TeamMember[] = [
30
30
  name: 'Christoph Nakazawa',
31
31
  links: [
32
32
  { icon: 'github', link: 'https://github.com/cpojer' },
33
- { icon: 'x', link: 'https://x.com/cpojer' },
33
+ { icon: 'x', link: 'https://x.com/cnakazawa' },
34
34
  { icon: 'bluesky', link: 'https://bsky.app/profile/christoph.nkzw.tech' },
35
35
  ],
36
36
  },
@@ -113,6 +113,7 @@ export const core: DefaultTheme.TeamMember[] = [
113
113
  name: 'JongKyung Lee',
114
114
  links: [
115
115
  { icon: 'github', link: 'https://github.com/jong-kyung' },
116
+ { icon: 'x', link: 'https://x.com/jongkyung_dev' },
116
117
  { icon: 'linkedin', link: 'https://www.linkedin.com/in/jong-kyung' },
117
118
  ],
118
119
  },
@@ -16,7 +16,42 @@ export default defineConfig({
16
16
  });
17
17
  ```
18
18
 
19
- Any value accepted by `vp create` as a first argument works here `@your-org` for an org picker, `@your-org:web` for a direct manifest entry, `vite:application` for a built-in, etc.
19
+ Any value accepted by `vp create` as a first argument works here: `@your-org` for an org picker, `@your-org:web` for a direct manifest entry, `vite:application` for a built-in, or the `name` of a local `create.templates` entry (see below).
20
+
21
+ ## `create.templates`
22
+
23
+ Declare local templates available to `vp create` inside a monorepo. Each entry is listed in the `vp create` picker, and selecting it (or passing its `name` as the template argument) runs the resolved `template`.
24
+
25
+ ```ts
26
+ import { defineConfig } from 'vite-plus';
27
+
28
+ export default defineConfig({
29
+ create: {
30
+ templates: [
31
+ {
32
+ name: 'component',
33
+ description: 'Internal UI component',
34
+ template: './tools/create-component',
35
+ },
36
+ { name: 'service', description: 'Backend service', template: 'service-generator' },
37
+ ],
38
+ },
39
+ });
40
+ ```
41
+
42
+ Each entry has:
43
+
44
+ | Field | Required | Notes |
45
+ | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
46
+ | `name` | yes | Identifier shown in the picker and accepted as `vp create <name>`. Must be unique within the array. The `vite:` prefix is reserved for built-in templates. |
47
+ | `description` | yes | One-line description shown in the picker. |
48
+ | `template` | yes | A workspace package name, a relative `./path` to a local package's directory (resolved against the workspace root), a `vite:*` built-in, a GitHub URL, or a full npm package name (e.g. `create-foo`). It is run as-is (not shorthand-expanded). |
49
+
50
+ `create.templates` is the source of truth for local templates: only entries listed here appear in the picker. Vite+ does not infer templates from package.json keywords. A `create.templates` entry whose `template` does not match any workspace package, or resolves to a local package without a `bin`, is reported as an error rather than falling through to an unrelated npm package.
51
+
52
+ [`vp create vite:generator`](/guide/create#code-generators) adds an entry here automatically (idempotently, preserving `defaultTemplate`); you can also edit the list by hand.
53
+
54
+ `create.defaultTemplate` can name a local entry, so bare `vp create` opens it directly.
20
55
 
21
56
  ## Precedence
22
57
 
@@ -10,10 +10,11 @@ export default defineConfig({
10
10
  build: {},
11
11
  preview: {},
12
12
 
13
- test: {},
14
- lint: {},
15
- fmt: {},
13
+ create: {},
16
14
  run: {},
15
+ fmt: {},
16
+ lint: {},
17
+ test: {},
17
18
  pack: {},
18
19
  staged: {},
19
20
  });
@@ -23,9 +24,10 @@ export default defineConfig({
23
24
 
24
25
  Vite+ extends the basic Vite configuration with these additions:
25
26
 
26
- - [`lint`](/config/lint) for Oxlint
27
+ - [`create`](/config/create) for project and template scaffolding defaults
28
+ - [`run`](/config/run) for Vite Task
27
29
  - [`fmt`](/config/fmt) for Oxfmt
30
+ - [`lint`](/config/lint) for Oxlint
28
31
  - [`test`](/config/test) for Vitest
29
- - [`run`](/config/run) for Vite Task
30
32
  - [`pack`](/config/pack) for tsdown
31
33
  - [`staged`](/config/staged) for staged-file checks
@@ -22,8 +22,17 @@ If you use [`vp create`](/guide/create) or [`vp migrate`](/guide/migrate), Vite+
22
22
  ```bash
23
23
  vp config
24
24
  vp config --hooks-dir .vite-hooks
25
+ vp config --no-hooks
26
+ vp config --no-agent
25
27
  ```
26
28
 
29
+ Use `--no-hooks` when you want `vp config` to leave existing Git hook setup unchanged. Use
30
+ `--no-agent` when you want it to skip updates to existing coding agent instruction files. You
31
+ can pass both flags when you want `vp config` to skip both setup steps.
32
+
33
+ You can also set `VITE_GIT_HOOKS=0` to disable hook installation from lifecycle scripts such as
34
+ `prepare` or `postinstall`.
35
+
27
36
  ### `vp staged`
28
37
 
29
38
  `vp staged` runs staged-file checks using the `staged` config from `vite.config.ts`. If you set up Vite+ to handle your commit hooks, it will automatically run when you commit your local changes.
@@ -27,7 +27,7 @@ Vite+ ships with these built-in templates:
27
27
  - `vite:monorepo` creates a new monorepo
28
28
  - `vite:application` creates a new application
29
29
  - `vite:library` creates a new library
30
- - `vite:generator` creates a new generator
30
+ - `vite:generator` creates a new code generator (monorepo only, see [Code Generators](#code-generators))
31
31
 
32
32
  ## Template Sources
33
33
 
@@ -35,7 +35,7 @@ Vite+ ships with these built-in templates:
35
35
 
36
36
  - Use shorthand templates like `vite`, `@tanstack/start`, `svelte`, `next-app`, `nuxt`, `react-router`, and `vue`
37
37
  - Use full package names like `create-vite` or `create-next-app`
38
- - Use local templates such as `./tools/create-ui-component` or `@your-org/generator-*`
38
+ - Use local monorepo templates declared in [`create.templates`](#code-generators) (for example an internal component or service generator)
39
39
  - Use remote templates such as `github:user/repo` or `https://github.com/user/template-repo`
40
40
 
41
41
  Run `vp create --list` to see the built-in templates and the common shorthand templates Vite+ recognizes.
@@ -44,15 +44,29 @@ Run `vp create --list` to see the built-in templates and the common shorthand te
44
44
 
45
45
  - `--directory <dir>` writes the generated project into a specific target directory
46
46
  - `--agent <name>` creates agent instructions files during scaffolding
47
+ - `--no-agent` skips agent instruction setup
47
48
  - `--editor <name>` writes editor config files
49
+ - `--no-editor` skips editor config setup
48
50
  - `--git` initialize a git repository
49
51
  - `--no-git` skips git repository initialization
50
52
  - `--hooks` enables pre-commit hook setup
51
53
  - `--no-hooks` skips hook setup
54
+ - `--package-manager <name>` uses a specified package manager (`pnpm`, `npm`, `yarn`, or `bun`)
55
+ - `--approve-builds` approves and runs gated dependency build scripts without prompting
52
56
  - `--no-interactive` runs without prompts
53
57
  - `--verbose` shows detailed scaffolding output
54
58
  - `--list` prints the available built-in and popular templates
55
59
 
60
+ ### Dependency build scripts
61
+
62
+ For security, pnpm, bun, and yarn (Berry) do not run a dependency's build scripts (`install` / `postinstall`, e.g. native builds like `better-sqlite3`) until you approve them. When a template adds such a dependency directly, `vp create` surfaces it after installing instead of leaving the project in a half-built state:
63
+
64
+ - Interactive: you are asked which of those dependencies to approve and build (nothing is selected by default).
65
+ - Non-interactive: a note lists them and points at `vp pm approve-builds`.
66
+ - `--approve-builds`: approves and builds them automatically, so non-interactive runs (CI) can produce a ready-to-use project.
67
+
68
+ Approval is recorded the way each package manager expects: pnpm's `allowBuilds`, bun's `trustedDependencies`, or yarn's `dependenciesMeta.<pkg>.built` (in the workspace root manifest). Transitive build scripts you did not choose (e.g. `esbuild` pulled in by Vite) are left at the package manager's defaults and are not surfaced. npm runs build scripts by default, so there is nothing to approve there.
69
+
56
70
  ## Template Options
57
71
 
58
72
  Arguments after `--` are passed directly to the selected template.
@@ -89,6 +103,96 @@ vp create github:user/repo
89
103
  vp create https://github.com/user/template-repo
90
104
  ```
91
105
 
106
+ ## Code Generators
107
+
108
+ Monorepos often need to scaffold their own building blocks: a UI component, a service, or an internal package that follows house conventions. Vite+ supports this through generator packages powered by [Bingo](https://www.create.bingo/) templates.
109
+
110
+ ### Scaffold a generator
111
+
112
+ Inside a Vite+ monorepo, run:
113
+
114
+ ```bash
115
+ vp create vite:generator
116
+ ```
117
+
118
+ This requires a monorepo workspace. If you don't have one yet, create it first with `vp create vite:monorepo`.
119
+
120
+ The scaffolded generator package contains:
121
+
122
+ - `src/template.ts` defines the template using `createTemplate` from `bingo`: an options schema built with [Zod](https://zod.dev/) and a `produce()` function that returns the files to generate
123
+ - `bin/index.ts` is the CLI entry, powered by Bingo's `runTemplateCLI`
124
+
125
+ If the monorepo has a parent directory matching `generators` or `tools`, the new package is placed there by default.
126
+
127
+ ### Registration
128
+
129
+ Local generators are declared in [`create.templates`](/config/create#create-templates) in the monorepo's `vite.config.ts`. This is the source of truth: only registered templates appear in the `vp create` picker.
130
+
131
+ `vp create vite:generator` registers the generator for you, adding an entry to `create.templates` in the root `vite.config.ts`:
132
+
133
+ ```ts
134
+ import { defineConfig } from 'vite-plus';
135
+
136
+ export default defineConfig({
137
+ create: {
138
+ templates: [
139
+ { name: 'my-generator', description: 'Generate new components', template: 'my-generator' },
140
+ ],
141
+ },
142
+ });
143
+ ```
144
+
145
+ Re-running is idempotent (no duplicate entries), and an existing `create.defaultTemplate` is preserved. You can also add entries by hand, for example to register a template you didn't scaffold this way. The `template` value is the generator's workspace package name, or a relative `./path` to it.
146
+
147
+ ### Run a generator
148
+
149
+ Inside the monorepo, run `vp create` and pick the generator from the template list, or pass its entry `name` directly:
150
+
151
+ ```bash
152
+ # Interactive mode lists registered local templates alongside the built-ins
153
+ vp create
154
+
155
+ # Run a registered template by its name
156
+ vp create component
157
+
158
+ # Pass options to the generator after --
159
+ vp create component -- --name @your-org/button
160
+ ```
161
+
162
+ When the generator depends on `bingo`, Vite+ appends `--skip-requests` automatically so it skips Bingo's outbound network requests (such as GitHub API calls).
163
+
164
+ After the generator runs, the created package goes through the regular monorepo integration: workspace registration, dependency installation, and formatting.
165
+
166
+ ### Customize a generator
167
+
168
+ Edit `src/template.ts` to define the options and the files to produce:
169
+
170
+ ```ts
171
+ import { createTemplate } from 'bingo';
172
+ import { z } from 'zod';
173
+
174
+ export default createTemplate({
175
+ options: {
176
+ name: z.string().describe('Package name'),
177
+ },
178
+ async produce({ options }) {
179
+ return {
180
+ files: {
181
+ 'package.json': JSON.stringify({ name: options.name, version: '0.0.0' }, null, 2),
182
+ src: {
183
+ 'index.ts': `export const name = '${options.name}';\n`,
184
+ },
185
+ },
186
+ };
187
+ },
188
+ });
189
+ ```
190
+
191
+ - `options` defines the generator's prompts and flags using Zod schemas
192
+ - `produce()` returns the [files](https://www.create.bingo/build/concepts/creations#files) to create, plus optional [scripts](https://www.create.bingo/build/concepts/creations#scripts) to run after generation and [suggestions](https://www.create.bingo/build/concepts/creations#suggestions) to print for the user
193
+
194
+ See the [Bingo documentation](https://www.create.bingo/) for the full template API.
195
+
92
196
  ## Organization Templates
93
197
 
94
198
  An organization can publish a curated set of templates under a single npm scope by shipping an `@org/create` package whose `package.json` carries a `createConfig.templates` manifest. Once published, `vp create @org` opens an interactive picker over those templates.
package/docs/guide/env.md CHANGED
@@ -6,7 +6,16 @@
6
6
 
7
7
  Managed mode is on by default, so `node`, `npm`, and related shims resolve through Vite+ and pick the right Node.js version for the current project.
8
8
 
9
- When a project declares `packageManager` in `package.json`, matching package-manager shims also use that exact package-manager version. For example, `packageManager: "npm@10.9.4"` makes both `npm` and `npx` run through npm 10.9.4. Alias pairs follow the installed package-manager shims: `npm`/`npx`, `pnpm`/`pnpx`, `yarn`/`yarnpkg`, and `bun`/`bunx`. Vite+ does not translate mismatched commands, so a project pinned to `pnpm` still lets `npm` fall back to the npm that comes with the resolved Node.js runtime.
9
+ The project Node.js version is resolved from these sources, in priority order:
10
+
11
+ 1. `.node-version` file (current or parent directories)
12
+ 2. `devEngines.runtime` in `package.json` (the [devEngines standard](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines))
13
+ 3. `engines.node` in `package.json`
14
+ 4. The global default (`vp env default`), then the latest LTS
15
+
16
+ `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.
17
+
18
+ When a project declares `packageManager` (or `devEngines.packageManager`) in `package.json`, matching package-manager shims also use that package-manager version. For example, `packageManager: "npm@10.9.4"` makes both `npm` and `npx` run through npm 10.9.4. Alias pairs follow the installed package-manager shims: `npm`/`npx`, `pnpm`/`pnpx`, `yarn`/`yarnpkg`, and `bun`/`bunx`. Vite+ does not translate mismatched commands, so a project pinned to `pnpm` still lets `npm` fall back to the npm that comes with the resolved Node.js runtime.
10
19
 
11
20
  By default, Vite+ stores its managed runtime and related files in `~/.vite-plus`. If needed, you can override that location with `VP_HOME`.
12
21
 
@@ -60,8 +69,8 @@ In CI, `vp env use` can still run without shell initialization. It writes a temp
60
69
  ### Manage
61
70
 
62
71
  - `vp env default` sets or shows the global default Node.js version
63
- - `vp env pin` pins a Node.js version in the current directory
64
- - `vp env unpin` removes `.node-version` from the current directory
72
+ - `vp env pin` pins a Node.js version in the current directory: an existing `.node-version` keeps being updated; otherwise the pin is written to `package.json#devEngines.runtime`; `.node-version` is only created when the directory has no `package.json`. Use `--target node-version` or `--target dev-engines` to choose explicitly. An existing `engines.node` is never modified.
73
+ - `vp env unpin` removes the pin from the same source `vp env pin` would write
65
74
  - `vp env use` sets a Node.js version for the current shell session
66
75
  - `vp env install` installs a Node.js version
67
76
  - `vp env uninstall` removes an installed Node.js version
@@ -78,7 +87,7 @@ In CI, `vp env use` can still run without shell initialization. It writes a temp
78
87
 
79
88
  ## Project Setup
80
89
 
81
- - Pin a project version with `.node-version`
90
+ - Pin a project version with `vp env pin`
82
91
  - Use `vp install`, `vp dev`, and `vp build` normally
83
92
  - Let Vite+ pick the right runtime for the project
84
93
 
@@ -86,7 +95,7 @@ In CI, `vp env use` can still run without shell initialization. It writes a temp
86
95
 
87
96
  ```bash
88
97
  # Setup
89
- vp env setup # Create shims for node, npm, npx
98
+ vp env setup # Create shims for node, npm, npx, corepack
90
99
  vp env on # Use Vite+ managed Node.js
91
100
  vp env print # Print shell snippet for this session
92
101
 
@@ -111,6 +120,25 @@ vp node script.js # Shorthand: run a Node.js script with the resolve
111
120
  vp node -e "console.log(1+1)" # Shorthand: forward any node flag or argument
112
121
  ```
113
122
 
123
+ ## Corepack
124
+
125
+ Vite+ creates a `corepack` shim by default, so corepack works without a system Node.js installation:
126
+
127
+ - On Node.js 24 and earlier, the shim runs the corepack bundled with the resolved Node.js version.
128
+ - On Node.js 25 and later, where corepack is no longer bundled, Vite+ installs corepack as a managed global package on first use. Only the `corepack` binary is linked; run `vp install -g corepack` yourself if you also want the package's pnpm/yarn launchers exposed directly.
129
+ - If you install corepack explicitly with `vp install -g corepack`, that installation is always preferred.
130
+
131
+ `corepack enable` normally creates `pnpm`/`yarn` launchers next to the corepack binary, which under Vite+ would not be on `PATH`. The shim fixes this by defaulting `--install-directory` to `VP_HOME/bin`, so after `corepack enable` the launchers are available everywhere and still resolve the project's Node.js and package-manager versions:
132
+
133
+ ```bash
134
+ corepack enable # pnpm and yarn now resolve via corepack
135
+ corepack disable # Remove the pnpm/yarn launchers again
136
+ ```
137
+
138
+ The launchers reference the corepack copy that created them. If that copy is later removed (for example by uninstalling the Node.js version it shipped with), rerun `corepack enable` to recreate them.
139
+
140
+ Shims owned by Vite+ (`npm`, `npx`, and binaries installed with `vp install -g`) are protected: if corepack removes or replaces them, Vite+ restores them and prints a warning.
141
+
114
142
  ## Custom Node.js Mirror
115
143
 
116
144
  By default, Vite+ downloads Node.js from `https://nodejs.org/dist`. If you're behind a corporate proxy or need to use an internal mirror (e.g., Artifactory), set the `VP_NODE_DIST_MIRROR` environment variable:
@@ -104,10 +104,11 @@ Vite+ can handle the entire local frontend development cycle from starting a pro
104
104
  ### Execute
105
105
 
106
106
  - [`vp run`](/guide/run) runs tasks across workspaces with caching.
107
- - [`vp cache clean`](/guide/cache) clears task cache entries.
108
- - [`vpx`](/guide/vpx) downloads and runs binaries globally.
109
107
  - [`vp exec`](/guide/vpx) runs local project binaries.
108
+ - [`vp node`](/guide/env) runs Node.js scripts with the resolved Vite+ environment.
110
109
  - [`vp dlx`](/guide/vpx) downloads and runs package binaries without adding them as dependencies.
110
+ - [`vp cache clean`](/guide/cache) clears task cache entries.
111
+ - [`vpx`](/guide/vpx) downloads and runs binaries globally.
111
112
 
112
113
  ### Build
113
114
 
@@ -117,7 +118,8 @@ Vite+ can handle the entire local frontend development cycle from starting a pro
117
118
 
118
119
  ### Manage Dependencies
119
120
 
120
- - [`vp add`](/guide/install), [`vp remove`](/guide/install), [`vp update`](/guide/install), [`vp dedupe`](/guide/install), [`vp outdated`](/guide/install), [`vp why`](/guide/install), and [`vp info`](/guide/install) wrap package-manager workflows.
121
+ - [`vp add`](/guide/install), [`vp remove`](/guide/install), [`vp update`](/guide/install), [`vp dedupe`](/guide/install), [`vp outdated`](/guide/install), [`vp list`](/guide/install), [`vp why`](/guide/install), and [`vp info`](/guide/install) wrap package-manager workflows.
122
+ - [`vp link`](/guide/install), [`vp unlink`](/guide/install), and [`vp rebuild`](/guide/install) cover local package links and native module rebuilds.
121
123
  - [`vp pm <command>`](/guide/install) calls other package manager commands directly.
122
124
 
123
125
  ### Maintain
@@ -9,18 +9,37 @@ Use Vite+ to manage dependencies across pnpm, npm, Yarn, and Bun. Instead of swi
9
9
  Vite+ detects the package manager from the workspace root in this order:
10
10
 
11
11
  1. `packageManager` in `package.json`
12
- 2. `pnpm-workspace.yaml`
13
- 3. `pnpm-lock.yaml`
14
- 4. `yarn.lock` or `.yarnrc.yml`
15
- 5. `package-lock.json`
16
- 6. `bun.lock` or `bun.lockb`
17
- 7. `.pnpmfile.cjs` or `pnpmfile.cjs`
18
- 8. `bunfig.toml`
19
- 9. `yarn.config.cjs`
20
-
21
- If none of those files are present, `vp` falls back to `pnpm` by default. Vite+ automatically downloads the matching package manager and uses it for the command you ran.
22
-
23
- The explicit `packageManager` field also affects matching package-manager shims. If a project has `packageManager: "npm@10.9.4"`, `npm` and `npx` use npm 10.9.4. Other generated alias pairs behave the same way: `pnpm`/`pnpx`, `yarn`/`yarnpkg`, and `bun`/`bunx`. Mismatched tools are not translated; `npm` in a `pnpm` project still resolves as npm.
12
+ 2. `devEngines.packageManager` in `package.json`
13
+ 3. `pnpm-workspace.yaml`
14
+ 4. `pnpm-lock.yaml`
15
+ 5. `yarn.lock` or `.yarnrc.yml`
16
+ 6. `package-lock.json`
17
+ 7. `bun.lock` or `bun.lockb`
18
+ 8. `.pnpmfile.cjs` or `pnpmfile.cjs`
19
+ 9. `bunfig.toml`
20
+ 10. `yarn.config.cjs`
21
+
22
+ If none of those files are present, `vp` falls back to `pnpm` by default. Vite+ automatically downloads the matching package manager and uses it for the command you ran. When detection comes from lockfiles or config files, the resolved version is written to `devEngines.packageManager` so future runs are deterministic; projects that already declare `packageManager` or `devEngines.packageManager` are left as-is.
23
+
24
+ The [`devEngines.packageManager`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines) field accepts a single object or an array of objects, and its `version` may be a semver range:
25
+
26
+ ```json
27
+ {
28
+ "devEngines": {
29
+ "packageManager": {
30
+ "name": "pnpm",
31
+ "version": "^11.0.0",
32
+ "onFail": "download"
33
+ }
34
+ }
35
+ }
36
+ ```
37
+
38
+ A range resolves to an already-downloaded satisfying version when possible, otherwise to the latest satisfying version from the npm registry. The range itself stays the source of truth; Vite+ never freezes it into an exact `packageManager` pin. When both `packageManager` and `devEngines.packageManager` are declared, the `packageManager` field drives selection and Vite+ warns when it does not satisfy the devEngines constraint (`vp env doctor` shows details).
39
+
40
+ Vite+ currently downloads the declared package manager (the `onFail: "download"` behavior); the other `onFail` values are accepted but not yet differentiated.
41
+
42
+ The explicit `packageManager` field (or the `devEngines.packageManager` declaration) also affects matching package-manager shims. If a project has `packageManager: "npm@10.9.4"`, `npm` and `npx` use npm 10.9.4. Other generated alias pairs behave the same way: `pnpm`/`pnpx`, `yarn`/`yarnpkg`, and `bun`/`bunx`. Mismatched tools are not translated; `npm` in a `pnpm` project still resolves as npm.
24
43
 
25
44
  ## Usage
26
45
 
@@ -75,8 +75,8 @@ Migrate this project to Vite+. Vite+ replaces the current split tooling around r
75
75
  After the migration:
76
76
 
77
77
  - Confirm `vite` imports were rewritten to `vite-plus` where needed
78
- - Confirm `vitest` imports were rewritten to `vite-plus/test` where needed
79
- - On pnpm, keep the `vite` / `vitest` entries that `vp migrate` aliased to the Vite+ packages so the workspace override stays effective; with other package managers you can remove them once those rewrites are confirmed
78
+ - Confirm `vitest` imports were rewritten to `vite-plus/test` (and `@vitest/browser*` to `vite-plus/test/browser*`) where needed
79
+ - Remove old `vite`, `vitest`, and `@vitest/browser*` dependencies only after those rewrites are confirmed `vite-plus` ships them as direct deps
80
80
  - Move remaining tool-specific config into the appropriate blocks in `vite.config.ts`
81
81
 
82
82
  Command mapping to keep in mind:
@@ -96,20 +96,30 @@ Summarize the migration at the end and report any manual follow-up still require
96
96
 
97
97
  ### Vitest
98
98
 
99
- Vitest is automatically migrated through `vp migrate`. If you are migrating manually, you have to update all the imports to `vite-plus/test` instead:
99
+ Vitest is automatically migrated through `vp migrate`. `vite-plus` re-exports upstream `vitest@4.x` under `vite-plus/test*`, so for node-mode tests a single `vite-plus` install is enough — you no longer need to install `vitest` directly.
100
+
101
+ Browser mode is more nuanced. `vite-plus` bundles the base browser runtime (`@vitest/browser`) and the preview provider (`@vitest/browser-preview`), but the **Playwright** and **WebdriverIO** providers stay opt-in: `@vitest/browser-playwright` (with its `playwright` peer) and `@vitest/browser-webdriverio` (with its `webdriverio` peer) are **not** shipped with `vite-plus`, so non-browser projects never pull them in. `vp migrate` detects the provider you actually use and adds it — pinned to the bundled vitest version — together with its framework. If you migrate manually and use one of these providers, install the provider package and its framework yourself so `vite-plus/test/browser-playwright` / `vite-plus/test/browser-webdriverio` can resolve.
102
+
103
+ If you are migrating manually, update all the imports to `vite-plus/test*` instead:
100
104
 
101
105
  ```ts
102
106
  // before
107
+ import { defineConfig } from 'vitest/config';
103
108
  import { describe, expect, it, vi } from 'vitest';
109
+ import { playwright } from '@vitest/browser-playwright';
104
110
 
105
111
  const { page } = await import('@vitest/browser/context');
106
112
 
107
113
  // after
114
+ import { defineConfig } from 'vite-plus';
108
115
  import { describe, expect, it, vi } from 'vite-plus/test';
116
+ import { playwright } from 'vite-plus/test/browser-playwright';
109
117
 
110
118
  const { page } = await import('vite-plus/test/browser/context');
111
119
  ```
112
120
 
121
+ `declare module 'vitest'` / `declare module '@vitest/browser*'` augmentations are intentionally **not** rewritten — `vite-plus/test*` is a thin re-export of upstream `vitest*`, so type augmentations have to target the upstream module identity to merge correctly. Leave those `declare module` statements pointing at `'vitest'` / `'@vitest/browser*'`.
122
+
113
123
  ### tsdown
114
124
 
115
125
  If your project uses a `tsdown.config.ts`, move its options into the `pack` block in `vite.config.ts`:
@@ -67,9 +67,9 @@ export default defineConfig({
67
67
 
68
68
  ## Slow config loading caused by heavy plugins
69
69
 
70
- When `vite.config.ts` imports heavy plugins at the top level, every `import` is evaluated eagerly, even for commands like `vp lint` or `vp fmt` that don't need those plugins. This can make config loading noticeably slow.
70
+ When `vite.config.ts` imports plugins at the top level, they are evaluated for every command, including `vp lint`, `vp fmt`, editor integrations, and long-lived background processes. This can make config loading slow and may trigger plugin setup side effects, such as reading files, starting watchers, or connecting to services.
71
71
 
72
- Use `lazyPlugins` to wrap plugin loading. Plugins are only loaded for commands that need them (`dev`, `build`, `test`, `preview`), and skipped for everything else:
72
+ Use `lazyPlugins` to load plugins only when the Vite pipeline actually runs (`dev`, `build`, `test`, `preview`):
73
73
 
74
74
  ```ts [vite.config.ts]
75
75
  import { defineConfig, lazyPlugins } from 'vite-plus';