Join the Vite+ ecosystem: `vp create @push-based/ngp`, `vp migrate`, and docs for both

Aperta
#13 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
20/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
angular, typescript, vite
Ambito
tooling

Direzione di ricerca

Start with the linked sub-issues, especially #14–#18, and the repository's CLAUDE.md; this epic depends on a scaffolder, plugin compatibility work, documentation, and release automation. The issue records decisions and investigation results, but does not identify a single bounded change or completion check. It is complete when the listed sub-issues deliver the Vite+ create, migrate, documentation, and release paths.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

documentation feature

Type: epic. Labels: feature, documentation.

Goal

An Angular developer with Vite+ installed runs one command and gets a working app built by vite-plugin-ngp:

vp create @push-based/ngp my-app
cd my-app
vp dev

An existing app that already uses the plugin runs vp migrate and keeps working. Both paths are documented on the site, including SSR and the rest of the Vite+ toolchain (vp test, vp check, vp lint, vp fmt, vp build, vp staged).

This issue records what was investigated, the decisions taken, and the sub-issues.

What was found (7 November 2026)

Sources: viteplus.dev/guide/create, viteplus.dev/config/create, viteplus.dev/guide/migrate, migration rules, and the source of packages/cli/src/create/ in voidzero-dev/vite-plus on main. Vite+ is at 1.5.0 on npm (4 November 2026). Spike results below were run locally on macOS with Node 26, pnpm 10.15, @push-based/[email protected] and [email protected].

How vp create <name> resolves a template

There is no registry and no hard-coded framework list. discovery.ts resolves the first argument in this order:

  1. @scope or @scope:<entry> → reads @scope/create from npm and its package.json#createConfig.templates manifest, shows a picker.
  2. A name from create.templates in the root vite.config.ts (monorepo-local only).
  3. vite:* → built-ins (vite:application is just create-vite, vite:library is degit of a tsdown template, vite:monorepo is bundled).
  4. github:user/repo or a GitHub URL → degit.
  5. Anything else is expanded the way npm create does: @push-based/ngp → @push-based/create-ngp, ngp → create-ngp, run through the chosen package manager's runner (pnpm dlx create-ngp, npx create-ngp, yarn dlx, bun x), after an npm existence check. Three special cases exist (svelte → sv, nitro → create-nitro-app, @tanstack/start → @tanstack/cli); the "Popular Templates" list printed by vp create --list is display-only.

So vp create @push-based/ngp works the day @push-based/create-ngp is on npm, with no change upstream. What vp passes to the child:

  • Arguments after the template name go through unchanged. The target directory is not prepended for npm templates (it is for vite:application and GitHub templates), so vp create @push-based/ngp my-app runs @push-based/create-ngp my-app, and without a directory the scaffolder gets no args.
  • --no-interactive, --package-manager, --git, --hooks are consumed by vp and not forwarded. Only vp create @push-based/ngp -- --no-interactive reaches the template. --directory is rejected for npm templates.
  • No environment variable marks "running under vp". The child inherits process.env with vp's package-manager bin on PATH. (npm_config_user_agent is readable, as under any pnpm dlx.)

After the template exits, vp runs rewriteStandaloneProject on the new directory, then git init, agent/editor files, hooks, vp install, vp fmt. That rewrite:

  • adds vite-plus to devDependencies, and only if vite is already declared points it at npm:@voidzero-dev/vite-plus-core@<version> (via catalog: and pnpm-workspace.yaml overrides under pnpm);
  • removes vitest unless the project imports it directly, otherwise pins it to the bundled 5.1.0;
  • rewrites scripts: vite → vp dev, vite build → vp build, vitest → vp test, adds "prepare": "vp config";
  • rewrites vite/vitest imports to vite-plus and vite-plus/test in config files and sources;
  • wraps the plugins array in lazyPlugins(...) and injects fmt: {}, a lint block (vite-plus/prefer-vite-plus-imports, typeAware, typeCheck) and staged, unless the template's config already has those keys (fixed in #1836, June 2026);
  • writes AGENTS.md, .vite-hooks/, and .gitignore entries.
The @scope/create org picker, not pursued

Publishing @push-based/create with a createConfig.templates manifest would make vp create @push-based open a picker over org templates. It's an org-wide package with nothing tying it to ngp, and this project only owns ngp things, so it isn't part of this epic. Everything published here carries ngp in its name. If the org ever wants a picker, it's a separate package with its own owner, and its ngp entry would point at @push-based/create-ngp.

Getting into vp create --list and the default picker

Only by PR to vite-plus, as Svelte did (#857 → PR #982: a special case in expandCreateShorthand plus the display list). Worth asking once create-ngp has shipped and works under vp create unattended. Not a dependency for anything here.

Does the plugin run under Vite+ today? Yes, with one dependency detail

Spike 1, a fresh minimal app with [email protected], defineConfig from vite-plus, and ngp() from the published plugin:

Command Result
vp build Builds; type-check runs; 97 kB index-*.js
vp dev Serves; /src/app/app.ts comes back compiled; /@ngp/type-check-client.js injected
vp test run (spec imports from vite-plus/test, jsdom, TestBed setup from the Testing page) 1 passed, Vitest 5.1.0
vp check after vp check --fix passes: fmt, lint (type-aware) and tsgo type errors all clean on Angular sources
vp lint with no .gitignore lints dist/ and node_modules/.pnpm/…/typescript.js. A _gitignore in the template avoids it

The one catch: the plugin imports createFilter, parseSync, createBuilder, parseAstAsync and types from vite, and peer-depends on vite ^8.3.0. A project that depends only on vite-plus has no vite in node_modules, so the plugin fails to load. It works once vite is declared as npm:@voidzero-dev/[email protected] (what vp migrate and rewriteStandaloneProject write, but only when vite was already declared). So the template must declare vite and the docs must say so. The alias package's version is 1.5.0, which does not satisfy ^8.3.0; pnpm's migration adds peerDependencyRules.allowAny: [vite], npm/yarn users would see a peer warning. Sub-issue 2 handles this.

Spike 2, vp migrate --no-interactive on an app set up per the Getting started and Testing pages (plain [email protected], [email protected], vitest.config.ts): migration applied cleanly, exactly the rewrite listed above, and vp build, vp test and vp check passed afterwards. vitest.config.ts was kept, with its import rewritten to vite-plus. vp fmt reformatted the Angular sources to Oxfmt defaults (double quotes, 2-space), which is not the Angular style guide; a fmt block in the template can set singleQuote.

Patterns worth copying
  • create-vite (the template vite:application runs): @clack/prompts + mri, template-<name>/ directories copied file by file, _gitignore → .gitignore, package.json#name and <title> substituted, flags --template, --overwrite, --immediate/--no-immediate, --interactive/--no-interactive, --help, prints "Done. Now run:". vp passes --no-immediate to it so it doesn't install.
  • create-analog (the Angular precedent): prompts + minimist, no non-interactive mode, no --help, runs git init itself (which collides with vp's own git init). Don't copy that.
  • vp's own _gitignore / _npmrc / _yarnrc.yml rename convention, the same as create-vite's.

Decisions (agreed 7 November 2026)

  1. Publish @push-based/create-ngp as the vp create @push-based/ngp and npm create @push-based/ngp entry point. Scoped, like the plugin (decision 61): on npm only a scoped package belongs to the org. Both vp and npm expand @scope/name to @scope/create-name, so the command stays one word. The cost is that the bare vp create ngp doesn't resolve to it until vite-plus adds a special case upstream (sub-issue #19). The name is free on npm (checked 7 November 2026). It lives in this repo at packages/create-ngp, released by the same Nx release setup, and pins the same Angular and plugin versions as the plugin release it ships with.
  2. No @push-based/create org package. It would be org-scoped with no ngp in its name, so it doesn't belong to this project. The only package added is @push-based/create-ngp. The unscoped create-angular-app name is held by PushBased but not used: it reads as an official Angular scaffolder and names neither ngp nor PushBased. Decided 9 November 2026.
  3. The template emits a plain Vite project and lets vp's post-create rewrite convert it. There is no reliable "running under vp" signal (npm_config_user_agent says pnpm either way, and vp sets no variable), and spike 2 showed the rewrite does the right thing: vite aliased, scripts and imports rewritten, lazyPlugins, fmt/lint/staged injected. npm create @push-based/ngp users get exactly what Getting started describes. The cost is that under vp the generated vite.config.ts is rewritten after the fact, so the user sees a config nobody wrote by hand. The template declares vite as a devDependency so the rewrite aliases it, and ships fmt/lint keys only if the injected defaults turn out wrong for Angular. Revisit when the first user asks.
  4. Templates: app (CSR, routing, Vitest spec) and app-ssr (adds main.server.ts, provideClientHydration, a server.mjs from the playground). No Tailwind, Material or i18n options in v1; those are docs, not prompts.
  5. One docs page, site/content/vite-plus.md, "Using Vite+", in the Guide section, covering: create a new app, migrate an existing plugin app with vp migrate, migrate an ng build app (point to the existing page, then vp migrate), the toolchain commands and what each does with an Angular app, SSR under vp dev/vp build, and limits. Getting started gets a two-line pointer at the top. Status, Changelog, decisions and README entries per CLAUDE.md.
  6. Don't change the plugin's peer range yet. Document the vite alias and let the dependency question (sub-issue #15) decide whether peerDependencies.vite should admit @voidzero-dev/vite-plus-core or be dropped in favour of an optional import.

Sub-issues

  • #14 @push-based/create-ngp: the scaffolder and its templates (packages/create-ngp)
  • #15 Run the plugin under Vite+: the vite alias, peer dependency, and a CI job that runs vp build, vp dev, vp test, vp check on the playground
  • #16 Docs: "Using Vite+" page, Getting started pointer, status/changelog/decision entries, README
  • #18 Release: add the package to Nx release, the Publish workflow and trusted publishing; e2e that runs vp create @push-based/ngp against the published package after each release
  • #19 Upstream: propose a bare ngp shorthand and a vp create --list entry once #14 and #18 have shipped, and report the two create-path gaps (no "under vp" signal for templates, target directory not prepended for npm templates)

Open questions

  • Name of the shorthand. vp create @push-based/ngp is what we control. A bare ngp, and even more so angular, need an upstream special case; angular may be contested by the Angular team or Analog. Proposal: ship the scoped form, ask for ngp in #19, leave angular open.
  • How much the template should assume about Vite+. See decision 3; the recommendation is "nothing" for v1.
  • Angular pinning. Every generated package.json pins 22.3.0-next.4 exactly, like the docs. The template has to be re-released with every plugin release that moves ANGULAR_SHA. Nx projectsRelationship: fixed does that if both packages are in the release group.
  • Where vp migrate's prepare: vp config and .vite-hooks leave an ng build user who still has angular.json and Husky. The migrate rules say Husky is left alone with a warning. Document it, don't solve it.
  • Windows. Vite+ runs on Windows; the plugin is untested there. The docs page says so.
Lingua principale
TypeScript
Stelle
7
Fork
0
Merge medio
12h 24m
PR unite (30g)
13

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di push-based/vite-plugin-ngp

Tutte le issue di push-based/vite-plugin-ngp

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.