ReviewOS

stacks/very-happy-dom

fix(package): published register export points to missing files

#1598
Closed glennmichael123 opened this 8 days ago ·
8 days ago

Problem

very-happy-dom@0.1.10 declares the ./register export as ./dist/register.js with types at ./dist/register.d.ts, but neither file exists in the published npm tarball.

As a result, the documented preload fails:

error: preload not found "very-happy-dom/register"

The package root works and still exports GlobalRegistrator, so manual registration is available. The source repository also contains src/register.ts; this is a package build or files-output gap rather than a missing implementation.

Reproduction

npm pack very-happy-dom@0.1.10
tar -tf very-happy-dom-0.1.10.tgz | grep register
# no output

bun --preload very-happy-dom/register -e "console.log(typeof document)"
# error: preload not found "very-happy-dom/register"

Acceptance

  • The published tarball contains dist/register.js and dist/register.d.ts.
  • bun --preload very-happy-dom/register installs window and document.
  • A package-level test inspects the packed artifact, not only the source tree.
8 days ago

v0.1.11 is published and fixes the two reported symptoms. Leaving this open for the third acceptance item — see below.

The code fix was already on main in d398c4b, which added register and jsdom to the build entrypoints; 0.1.10 simply predated it. So this needed a release, not a change.

Verified against the tarball downloaded from the registry, not a local build:

$ tar -tf very-happy-dom-0.1.11.tgz | grep dist/register
package/dist/register.d.ts
package/dist/register.js

$ bun --preload very-happy-dom/register -e "console.log(typeof document, typeof window)"
object object
  • ✅ The published tarball contains dist/register.js and dist/register.d.ts.
  • ✅ bun --preload very-happy-dom/register installs window and document.
  • ❌ A package-level test inspects the packed artifact, not only the source tree.

That last one is the point of the issue and is still missing. Nothing currently fails if an entrypoint drops out of the build again — which is exactly how 0.1.10 shipped, and a source-tree test would not have caught it, because src/register.ts was present the whole time. The guard has to run npm pack (or read bun pm pack's output) and assert every path in exports exists inside the archive.

Worth noting dist/register.d.ts is export {};, which is correct rather than a build failure — the module is side-effect-only and exports nothing. A naive "the file is non-empty" assertion would be the wrong shape here.

8 days ago

Last acceptance item done in 9cbcf24. All three now hold:

  • ✅ The published tarball contains dist/register.js and dist/register.d.ts — shipped in v0.1.11, verified against the archive downloaded from the registry.
  • ✅ bun --preload very-happy-dom/register installs window and document.
  • ✅ A package-level test inspects the packed artifact.

The gap was narrower than it first looks. test/dist-export.test.ts already resolved every exports subpath, but against dist/ on disk — and files in package.json decides what the tarball carries. So dist can be complete while the archive is missing an entry point, and every existing check still passes. That is exactly the 0.1.10 shape: src/register.ts was present the whole time, which is why nothing reading the working tree caught it.

The new block asks bun pm pack --dry-run what it would actually include, and asserts every declared export subpath appears in that listing, plus specifically that the two documented drop-in entry points ship JS and not only types.

Verified by breaking it rather than by watching it pass. Narrowing files to ["README.md", "dist/index.js", "dist/index.d.ts"] fails it with the missing subpaths named:

+   "./register (types) -> ./dist/register.d.ts",
+   "./register (import) -> ./dist/register.js",
+   "./jsdom (types) -> ./dist/jsdom/index.d.ts",
+   "./jsdom (import) -> ./dist/jsdom/index.js",

Two details worth recording, since both are ways this guard could have been useless:

The parse guard asserts package.json is in the listing rather than a file count. package.json is packed whatever files says, so it fails only if bun's output format changes — which would otherwise leave the set empty, match nothing and pass vacuously. My first draft asserted size > 10, which failed on a legitimate packaging change under a test named "the pack listing was read at all"; a mislabelled failure trains people to ignore it.

The check runs in the test CI job, which builds before bun test, so it inspects a real build rather than stale output. No release needed — this is test-only, so v0.1.11 remains the fix.

Sign in to comment on this issue.