fix(core): resolve bundled Rolldown bindings via platform packages - #2313
Conversation
✅ Deploy Preview for viteplus-preview canceled.
|
f6f8ce8 to
fcca21b
Compare
|
@codex review |
Native binary sizes (
|
| Artifact | Format | Base | PR | Change |
|---|---|---|---|---|
vp (Linux x64) |
Binary | 10.52 MiB | 10.52 MiB | 0 B (0.00%) |
vp (Linux x64) |
gzip -9 | 4.55 MiB | 4.55 MiB | 0 B (0.00%) |
| NAPI (Linux x64) | Binary | 33.61 MiB | 33.61 MiB | 0 B (0.00%) |
| NAPI (Linux x64) | gzip -9 | 13.02 MiB | 13.02 MiB | 0 B (0.00%) |
vp (macOS ARM64) |
Binary | 7.84 MiB | 7.84 MiB | 0 B (0.00%) |
vp (macOS ARM64) |
gzip -9 | 3.95 MiB | 3.95 MiB | 0 B (0.00%) |
| NAPI (macOS ARM64) | Binary | 40.92 MiB | 40.92 MiB | 0 B (0.00%) |
| NAPI (macOS ARM64) | gzip -9 | 17.24 MiB | 17.24 MiB | -15 B (-0.00%) |
vp (Windows x64) |
Binary | 8.42 MiB | 8.42 MiB | 0 B (0.00%) |
vp (Windows x64) |
gzip -9 | 3.67 MiB | 3.67 MiB | 0 B (0.00%) |
| NAPI (Windows x64) | Binary | 27.77 MiB | 27.77 MiB | 0 B (0.00%) |
| NAPI (Windows x64) | gzip -9 | 10.86 MiB | 10.86 MiB | +2 B (+0.00%) |
| Trampoline (Windows x64) | Binary | 203.00 KiB | 203.00 KiB | 0 B (0.00%) |
| Trampoline (Windows x64) | gzip -9 | 97.91 KiB | 97.91 KiB | 0 B (0.00%) |
| Installer (Windows x64) | Binary | 4.47 MiB | 4.47 MiB | 0 B (0.00%) |
| Installer (Windows x64) | gzip -9 | 2.09 MiB | 2.09 MiB | -1 B (-0.00%) |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Registry bridge build (
|
| Package | Version |
|---|---|
vite-plus |
0.0.0-commit.3a79c350a1c28c9f491c7c4642e42ed426dda78d |
@voidzero-dev/vite-plus-core |
0.0.0-commit.3a79c350a1c28c9f491c7c4642e42ed426dda78d |
Install the Vite+ CLI built from this commit, then migrate a project:
# macOS / Linux
curl -fsSL https://vite.plus | VP_PR_VERSION=2313 bash# Windows (PowerShell)
$env:VP_PR_VERSION="2313"; irm https://vite.plus/ps1 | iexAfter installing, upgrade the current project's vite-plus to this test build with:
vp migrateOr point your package manager at the bridge registry https://registry-bridge.viteplus.dev/:
| Package manager | Registry config |
|---|---|
| npm / pnpm / Bun | .npmrc: registry=https://registry-bridge.viteplus.dev/ |
| Yarn (v2+) | .yarnrc.yml: npmRegistryServer: "https://registry-bridge.viteplus.dev/" |
Then pin the build (vite aliases to vite-plus-core; pnpm can use a catalog, npm an overrides entry):
{
"devDependencies": {
"vite-plus": "0.0.0-commit.3a79c350a1c28c9f491c7c4642e42ed426dda78d",
"vite": "npm:@voidzero-dev/vite-plus-core@0.0.0-commit.3a79c350a1c28c9f491c7c4642e42ed426dda78d"
}
}
🐳 Docker preview imageBuilt from this PR's registry bridge build:
# remove any stale local copy from a previous run, then pull fresh
docker rmi ghcr.io/voidzero-dev/vite-plus:pr-2313 2>/dev/null; docker pull ghcr.io/voidzero-dev/vite-plus:pr-2313Quick check: docker run --rm ghcr.io/voidzero-dev/vite-plus:pr-2313 vp --versionSee docs/guide/docker.md for usage. |
|
Verified the bridge build ( Baseline (repro as published, This build (catalog pinned to Same layout, core still resolving from the global store realpath, now working. Mechanism checks on the installed artifacts:
|
8fc4ef5 to
3a79c35
Compare
Release-built core resolves bundled Rolldown's native binding through vite-plus/binding, an export of a package core never declares, which breaks pnpm enable-global-virtual-store, Yarn PnP, and standalone core installs. The RFC keeps the per-platform rewrite direction from PR #2067 but moves the platform optionalDependencies pins out of the committed package.json and into the publish pipeline, mirroring how napi-rs injects the same packages into vite-plus.
Release builds now rewrite each supported @rolldown/binding-<platform> require to @voidzero-dev/vite-plus-<platform> (suffixes derived from the CLI's napi.targets via parseTriple) instead of collapsing all of them to vite-plus/binding, and rewrite each branch's version guard to core's version in the same specifier-anchored pattern. Branches for platforms Vite+ does not ship, the WASI fallback, and Rolldown's public VERSION export stay untouched, and the build fails if the rewrite counts diverge from the napi-rs loader shape. publish-native-addons.ts mirrors the napi-injected platform pins from packages/cli/package.json into core's optionalDependencies in both npm and pkg-pr-new modes, so core declares what its loader requires while the committed package.json stays pin-free and release version bumps, the dirty-tree check, and preview builds keep working. reusable-release-build.yml stamps packages/core/package.json so preview builds bake guard versions that match the bridge-served platform packages. Closes #2054 See rfcs/core-binding-resolution.md for the design.
binding-resolution-layout.spec.ts rebuilds pnpm's enable-global-virtual-store shape with stub packages and requires through it in a child process: the old collapsed rewrite fails with the exact #2054 error, the transform output resolves through the declared platform package, and the re-armed version guard rejects a mismatched platform package under NAPI_RS_ENFORCE_VERSION_CHECK. A PTY snapshot case cannot cover this because snapshot installs use dev-built core, which embeds the .node in dist and never takes the rewritten path. Writing the spec surfaced a transform gap: the guard rewrite only matched the bundled-chunk __require( form. It now also matches plain require( for raw CJS loader output; the build.ts count assertion would have caught the miss, but the transform should handle both.
The export existed only for the old collapsed @rolldown/binding-* rewrite. Nothing imports the specifier: the CLI loads its binding through a relative import, and no repo, dist, snapshot, or ecosystem reference exists. Old published cores that require it always pair with an old vite-plus through the exact version pin, so removal cannot strand them. The binding/ files still ship for the CLI's own relative import.
The rewrite transform now reports which platform suffixes it redirected, and the release build asserts set equality with the published platforms instead of a specifier/guard count ratio, so a dropped or renamed loader branch fails the build by name instead of shipping a partial rewrite. The platform-package prefix derives from the CLI's napi.packageName in both the transform and the publish script, removing three hard-coded copies of the scope string. Also: lazy-load @napi-rs/cli in build.ts (release-only, ~120ms saved on every dev core build), share one fresh package.json read in publish-native-addons.ts via readJsonFile, single-source the workflow's stamp/verify file list through GITHUB_ENV, simplify the guard regex and both specs, and shrink core BUNDLING.md's derived mapping table to examples plus a pointer at the napi.targets table.
3a79c35 to
e872dae
Compare
…t variable renames, and install fixes (#2325) Release vite-plus v0.2.8: monorepo target resolution, breaking `VP_*` environment variable renames, and install fixes. Bare `vp dev`/`build`/`preview`/`pack` at a monorepo root now resolve a target package instead of silently running against the root, and three Vite+-specific environment variables move to the `VP_*` prefix without compatibility aliases. Two failures that broke Vite+ before it could run are also fixed: the crash on container images that ship no CA certificates, and the missing Rolldown binding under pnpm's global virtual store. ### Breaking Changes - Rename three Vite+-specific environment variables to the `VP_*` prefix, with no compatibility aliases, so the old names stop working ([#2312](#2312)), by @jong-kyung: | Old | New | | --- | --- | | `VITE_LOG` | `VP_LOG` | | `VITE_GLOBAL_CLI_JS_SCRIPTS_DIR` | `VP_GLOBAL_CLI_JS_SCRIPTS_DIR` | | `VITE_UPDATE_TASK_TYPES` | `VP_UPDATE_TASK_TYPES` | Update any shell profile, CI job, or Dockerfile that sets the old names. ### Highlights - Resolve a target package for `vp dev`, `build`, `preview`, and `pack` at a monorepo root: interactive shells get a fuzzy package picker, non-interactive runs list the candidates and exit 1 instead of building the root, and a new global `-C <dir>` flag or a `defaultPackage` setting (a single directory, or an object mapping each of the four commands to its own directory) skips the prompt ([#2031](#2031), [#2305](#2305)), by @fengmk2 - Stop aborting with exit 134 on container images that ship no CA certificates (Debian slim, distroless): the shared HTTP client now retries once with the bundled Mozilla root list, like Node's own bundled roots, and reports a real error instead of panicking when it still cannot be built ([#2273](#2273), [#2295](#2295)), by @jbmusso and @fengmk2 - Resolve the bundled Rolldown binding through platform packages instead of an undeclared require back into `vite-plus`, fixing `Cannot find module 'vite-plus/binding'` under pnpm `enable-global-virtual-store` and in standalone `@voidzero-dev/vite-plus-core` installs ([#2313](#2313)), by @fengmk2 - Add `vp pm ci` for reproducible frozen-lockfile installs, and `vp pm patch` / `vp pm patch-commit` for editing dependencies in place on pnpm, bun, and Yarn Berry (npm and Yarn Classic warn and exit successfully) ([#2082](#2082), [#2308](#2308)), by @forehalo and @jong-kyung ### Features - Upgrade the bundled toolchain: vite `8.1.5` -> `8.2.0`, rolldown `1.2.0` -> `1.2.2`, oxlint `1.75.0` -> `1.76.0`, oxfmt `0.60.0` -> `0.61.0`, and Vite DevTools `0.4.5` -> `0.4.10` ([#2302](#2302), [#2311](#2311)), by @voidzero-guard[bot]. The new oxfmt and oxlint can flag code that passed before, so run `vp fmt` after upgrading if your CI runs `vp check`. - Read the Node.js version from `.nvmrc` when no other version source is present ([#2244](#2244)), by @BlankParticle - Support pnpm v12, which ships as a native binary: Vite+ now downloads the platform-specific `@pnpm/exe.*` package and generates native shims, so `pnpm` and `pnpx` work instead of failing to exec ([#2289](#2289)), by @jong-kyung - Verify the downloaded bun platform tarball against the registry `dist.integrity` hash ([#2310](#2310)), by @jong-kyung ### Fixes & Enhancements - Let `vp config` install the Git hook dispatcher without creating or modifying project hook scripts or staged-file configuration, so a custom `.vite-hooks/pre-commit` survives ([#2280](#2280)), by @TheAlexLichter - Nest immutable global package installs under `packages/<package>/<uuid>` instead of using `#` in the path, which Node treated as a URL fragment and which broke dynamic imports inside installed packages ([#2222](#2222)), by @liangmiQwQ - Keep the recorded version spec on global installs, so `vp update -g` follows a dist tag or range instead of silently resolving back to `latest`, `vp outdated -g` reports Wanted versus Latest, and `vp update -g --latest` explicitly moves packages back to `latest` ([#2249](#2249)), by @TheAlexLichter - Stop deleting a managed Node.js runtime that another process is concurrently installing ([#2248](#2248)), by @shulaoda - Preserve the real exit code when a spawned process is terminated by a signal on Unix ([#2154](#2154)), by @liangmiQwQ - Honor an explicit `vp create --package-manager` outside monorepos instead of inheriting the manager from a non-monorepo ancestor directory ([#2226](#2226)), by @jong-kyung - Scaffold the `vite:library` template into a directory that contains only `.git`, while still refusing to overwrite existing user files ([#2287](#2287)), by @RSS1102 - Render help for delegated commands from the local CLI, so `vp <command> --help` matches the installed toolchain instead of drifting ([#2184](#2184)), by @liangmiQwQ - Resolve `typeAware` and `typeCheck` options inherited through Oxlint `extends`, so `vp check --no-lint` runs and classifies type checking correctly ([#2228](#2228)), by @jong-kyung - Report `(no version)` instead of `unknown` when globally installing a local package that has no `version` field ([#2232](#2232)), by @liangmiQwQ ### Refactor - Rename the Git hooks environment variable to `VP_GIT_HOOKS`, keeping `VITE_GIT_HOOKS` working as a deprecated alias ([#2195](#2195)), by @dennybiasiolli - Consolidate the package manager infrastructure so typed command arguments are the source of truth for per-manager compatibility ([#2140](#2140)), by @forehalo - Generate the Zed language settings from a language list instead of 17 near-identical blocks ([#2294](#2294)), by @jong-kyung - Share the agent-file detect and write traversal helpers so both passes apply identical rules ([#2296](#2296)), by @jong-kyung - Drop redundant clippy allow attributes in the global CLI ([#2235](#2235)), by @shulaoda ### Docs - Avoid a duplicate `vp` installation step in the onboarding prompt ([#2291](#2291)), by @Arcadi4 - Recommend stacked pull requests for submitting changes ([#2281](#2281)), by @fengmk2 - Correct stale delegation comments in the global CLI ([#2236](#2236)), by @shulaoda - Improve the release draft review guidance in the release-manager skill ([#2285](#2285)), by @wan9chi ### Chore - Stop emitting unmet peer warnings for the `vite-plus` peer of oxfmt and oxlint on every install ([#2321](#2321)), by @fengmk2 - Remove duplicate direct dependency declarations so each build dependency is owned by one workspace ([#2318](#2318)), by @jong-kyung - Declare `@emnapi` peers where `@napi-rs/cli` is used ([#2319](#2319)), by @jong-kyung - Exclude `rollup-tests` from the workspace and update `basic-ftp` ([#2322](#2322)), by @fengmk2 - Remove unused `EnvConfig` fields ([#2320](#2320)), by @jong-kyung - Remove the obsolete peer dependency merger tool ([#2303](#2303)), by @jong-kyung - Stop the staging deploy from triggering on external pull requests ([#2293](#2293)), by @BlankParticle - Kill the real `vp` process, and kill it before its children, in the `env_install_interrupt` snapshot test ([#2299](#2299), [#2316](#2316)), by @fengmk2 - Suppress racy optimizer logs in the `vitest_browser_mode` snapshot test ([#2297](#2297)), by @fengmk2 - Remove the obsolete auto-install environment from the snapshot tests ([#2163](#2163)), by @liangmiQwQ ### Bundled Versions | Tool | Version | Source | | --------------- | ---------- | ------------------------------------------------------------------------------------------------- | | vite | `8.2.0` | [`fa79f9a`](vitejs/vite@fa79f9a) | | rolldown | `1.2.2` | [`872b98a`](rolldown/rolldown@872b98a) | | tsdown | `0.22.14` | [npm](https://npmx.dev/package/tsdown/v/0.22.14) | | vitest | `4.1.10` | [npm](https://npmx.dev/package/vitest/v/4.1.10) | | oxlint | `1.76.0` | [npm](https://npmx.dev/package/oxlint/v/1.76.0) | | oxlint-tsgolint | `7.0.2001` | [npm](https://npmx.dev/package/oxlint-tsgolint/v/7.0.2001) | | oxfmt | `0.61.0` | [npm](https://npmx.dev/package/oxfmt/v/0.61.0) | ### Upgrade ```bash vp upgrade ``` ### New Contributors @jbmusso, @Arcadi4, @dennybiasiolli, @RSS1102 **Full Changelog**: v0.2.7...v0.2.8 --- Merging this PR will trigger the release workflow. --------- Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com> Co-authored-by: MK <fengmk2@gmail.com>
Apply STE-style simplification to the report, scripts, and POC comment. Link every referenced nub/vp issue. Record the verified #667 status: PR #2313 fixes the core binding lookup, nub 0.7.2 materializes packages with undeclared imports per-project, and aube 1.37's slot layout resolves the old require. vp build passes on current versions.
Closes #2054. Design:
rfcs/core-binding-resolution.md. Solid edges are declared dependencies; dashed is an undeclared runtime require.Before
flowchart TD app["user project"] --> vp["vite-plus"] vp -->|"dependency, exact pin"| core["@voidzero-dev/vite-plus-core<br>(bundled Rolldown)"] vp -->|"optionalDependencies x8,<br>injected at publish"| plat["@voidzero-dev/vite-plus-*<br>platform packages (merged .node)"] core -.->|"require('vite-plus/binding'),<br>undeclared"| vp linkStyle 3 stroke:#d33,stroke-width:2pxRelease-built core reaches its Rolldown binding by requiring back into
vite-plus, an undeclared cycle that only resolves through pnpm's hidden hoist. pnpmenable-global-virtual-store, Yarn PnP, and standalone core installs (thevitealias) fail withCannot find module 'vite-plus/binding'.After
Core's bundled Rolldown requires the same platform packages
vite-plusalready uses, declared throughoptionalDependenciesinjected at publish time. No new packages, no cycle, core works standalone, and package managers dedupe the shared platform package.