Skip to content

fsCache default: node_modules/.cache/jiti never resolves for file-path instance ids (silent TMP_DIR fallback) #459

Description

@cad0p

Describe the bug

When fsCache: true (default) and the jiti instance id is a file path (the documented usage createJiti(import.meta.url)), the default cache dir almost never resolves to node_modules/.cache/jiti — it silently falls back to ${TMP_DIR}/jiti.

To reproduce

import { createJiti } from "jiti";
// id = a file nested below the package root, e.g. <pkg>/src/loader.ts
const jiti = createJiti("file:///home/user/my-pkg/src/loader.ts", { fsCache: true });
console.log(jiti.options.fsCache); // → /tmp/jiti  (not <pkg>/node_modules/.cache/jiti)

Even with <pkg>/node_modules present and writable.

Cause

getCacheDir() in src/cache.ts computes:

const nmDir = ctx.filename && resolve(ctx.filename, "../node_modules");

pathe.resolve treats the id (a FILE path, e.g. <pkg>/src/loader.ts) as a directory path, so "../node_modules" resolves relative to the file's parent directory: <pkg>/src/loader.ts/../node_modules → <pkg>/src/node_modules — which never exists. Same for ids inside node_modules (node_modules/foo/index.js → node_modules/foo/node_modules). The documented node_modules/.cache/jiti only materializes when the id sits directly at the project root (<proj>/index.js → <proj>/node_modules).

Impact

  • Transform cache lands in ${TMP_DIR}/jiti: volatile (wiped on reboot), shared machine-wide, unbounded growth (stale content-hash variants accumulate forever).
  • Every consumer whose entry module isn't at the project root silently re-pays cold babel transpiles after every reboot (measured: ~1.2s cold vs ~4ms warm for a small config graph).
  • On some systems TMPDIR handling has extra workarounds (pnpm #6140) that a proper node_modules cache dir avoids entirely.

Suggested fix

Use the file's directory:

const nmDir = ctx.filename && resolve(dirname(ctx.filename), "../node_modules");

(dirname is already imported in src/cache.ts.) This makes node_modules/.cache/jiti work for file ids at any depth; the tmpdir fallback remains for the no-node_modules case. Note: our consumer (pi-steering, cad0p/pi-steering#39) worked around it by passing an explicit fsCache string — an upstream fix would make the default correct for everyone.

Environment

  • jiti 2.7.0 (verified against current main, src/cache.ts getCacheDir), Node 22/24, Linux.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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