Skip to content

devcheck.mjs: trigger keys off NODE_ENV (false pos/neg), misses execArgv, no scoped-install guard, no tests #9

Description

@Shinrai

devcheck.mjs correctly namespaces its dev condition to uuid-dev (good — that's the right pattern for a normal module), but the check logic around it has several bugs. These are latent here because uuid's own test suite imports ../src/… directly and never imports the package entry, so devcheck is never actually exercised by CI — but the bugs bite a real developer.

The corrected reference implementation is @cldmv/holdmytask PR #12 (fix/devcheck-normal-module), which fixed the identical issues; this issue is to backport that.

Bugs

1. Trigger keys off NODE_ENV, which doesn't affect resolution

Current:

if (!nodeEnv || (!["", "development"].includes(nodeEnv) && !hasUUIDDev)) {  }

Only --conditions=uuid-dev selects src/ (via the ./main export); NODE_ENV has no effect on which tree resolves. So this logic is wrong in both directions:

  • False negative: NODE_ENV=development with no condition → stays silent, but the package is actually resolving to dist/. This is exactly the misconfiguration devcheck exists to catch, and it's silently allowed.
  • False positive: condition set but NODE_ENV unset → !nodeEnv fires and it nags, even though you're correctly on src/.

Correct trigger is condition-only: if (!hasUUIDDev) { … }.

2. Only checks NODE_OPTIONS, misses execArgv

const hasUUIDDev = process.env.NODE_OPTIONS?.includes("--conditions=uuid-dev");

node --conditions=uuid-dev file.mjs puts the flag in process.execArgv, not NODE_OPTIONS — and that's also how vitest passes conditions to its workers (a worker's NODE_OPTIONS is undefined while execArgv carries --conditions uuid-dev). So the CLI form and the vitest-worker form aren't detected. Check both:

const flags = (process.env.NODE_OPTIONS || "") + " " + process.execArgv.join(" ");
const hasUUIDDev = flags.includes("uuid-dev");

3. No installed-package guard (and the fleet's usual one is broken for scoped packages)

devcheck has no node_modules guard. npm publishes ship neither src/ nor devcheck.mjs, so it's moot for a registry install — but a git/tarball install includes them, and devcheck would then process.exit(1) inside the consumer's app. Add a guard, and make it scoped-aware (the common path.basename(path.dirname(__dirname)) === "node_modules" form misses node_modules/@cldmv/uuid, where the parent is the @cldmv scope dir):

const isInstalledPackage = __dirname.split(path.sep).includes("node_modules");

4. No tests

devcheck has no test coverage, which is how the above drifted. holdmytask PR #12 adds tests/DevCheck.test.vitest.mjs (9 cases: nags without condition; silent with condition via NODE_OPTIONS and via execArgv; NODE_ENV=development alone does not silence; still nags after a dist/ build; generic development condition rejected; skips in CI; skips when installed as a scoped dep; does nothing with no src/). Port it.

5. Minor: stale header

@Project: @cldmv/slothlet in the file header — copy-paste leftover, should be @cldmv/uuid.

Suggested fix

Port holdmytask PR #12's devcheck.mjs + tests/DevCheck.test.vitest.mjs, swapping holdmytask-devuuid-dev. No change needed to the uuid-dev condition itself or the ./main export.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions