Skip to content

exports should include "./package.json" #6

Description

@Shinrai

Summary

@cldmv/uuid's exports map does not expose ./package.json, so:

require.resolve("@cldmv/uuid/package.json")
// ERR_PACKAGE_PATH_NOT_EXPORTED

even though the package is installed and its entry resolves perfectly well:

require.resolve("@cldmv/uuid")
// …/.pnpm/@cldmv+uuid@1.1.2/node_modules/@cldmv/uuid/index.cjs

Current map (v1.1.2) lists ., ./devcheck, ./main.

Why it matters

Resolving <name>/package.json is the conventional way tooling locates a package's directory on disk — you can't use the entry, because an exports map may point it anywhere, and you often need the package root rather than a module. Any tool doing dependency-graph or packaging work uses this, so a package that omits it breaks those tools specifically.

Worse, it breaks silently. The natural way to handle an unresolvable specifier is to skip it — optional deps and node: builtins land in the same bucket — so the omission turns into "this dependency quietly wasn't processed" rather than an error at the point of failure.

How it surfaced

@cldmv/rummage's web build stages each extension's dependency tree so extensions can run server-side. It resolved each dependency via <name>/package.json. That worked for every other package in the graph and threw here, so @cldmv/uuid was never staged.

The only symptom was several extensions failing to activate in a running server, with Cannot find package '@cldmv/uuid' — several layers away from the actual cause, and only visible at all because that build had just gained activation-failure logging.

rummage now falls back to resolving the entry and walking up to the owning package, so it tolerates this. But the fallback exists to work around a defect that shouldn't be there, and every other consumer has to write the same workaround.

Fix

{
  "exports": {
    ".": { "…": "" },
    "./devcheck": { "…": "" },
    "./main": { "…": "" },
    "./package.json": "./package.json"
  }
}

This is standard practice and has no downside — the file is already readable from the package directory; the exports map is the only thing preventing resolution through the specifier.

Related

A fleet-wide sweep to check every @cldmv/* package for this is tracked in packrat's docs/future-features.md (Repo hygiene sweeps) — packrat already scans every repo per profile, so it fits as a detector there. @cldmv/uuid is the one confirmed case so far; others are likely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumShould be addressed in the normal course of developmentstatus: confirmedThe issue has been verified and reproduced by a maintainertype: bugSomething is broken or not behaving as expected

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions