mirrorPackage

tcmts.cli.flight.mirrorPackage · #24ttt2jh · term · runs on the server

uses node:path

Server code's copy of an installed package (entry, its directory under the cache's node_modules: pnpm's .pnpm/<entry>, or npm's <name>, @scope/<name>), at that path under the cache's server_modules: its files hard-linked (nothing copied), its links to the packages it uses as they are, and (pnpm's, beside it in .pnpm) those packages copied too; npm's are found by name in node_modules, so useFlight makes their copies as they're asked for. Node keeps CommonJS modules by their paths, and remembers what a directory's require("react") found: a copy at its own paths gets its own, so server code's React (the react-server condition's) and server rendering's (tcm dev loads it with Node) never stand in for each other. Made once.

import fs from "node:fs";
import path from "node:path";

export function mirrorPackage(cacheDir: string, entry: string): void {
  const to = path.join(cacheDir, "server_modules", entry);
  if (fs.existsSync(to)) return;
  const from = path.join(cacheDir, "node_modules", entry);
  const making = `${to}.${process.pid}`;
  const uses = new Set<string>();
  const copy = (src: string, dst: string) => {
    for (const e of fs.readdirSync(src, { withFileTypes: true })) {
      const s = path.join(src, e.name);
      const d = path.join(dst, e.name);
      if (e.isSymbolicLink()) {
        const target = fs.readlinkSync(s);
        fs.symlinkSync(target, d);
        // (pnpm's links are relative: one to a package beside this one points at its copy)
        const other = /^(?:\.\.\/)+([^/]+)\/node_modules\//.exec(target)?.[1];
        if (
          other &&
          entry.startsWith(".pnpm/") &&
          `.pnpm/${other}` !== entry &&
          !path.isAbsolute(target)
        )
          uses.add(`.pnpm/${other}`);
      } else if (e.isDirectory()) {
        fs.mkdirSync(d);
        copy(s, d);
      } else {
        try {
          fs.linkSync(s, d);
        } catch {
          fs.copyFileSync(s, d);
        }
      }
    }
  };
  fs.mkdirSync(making, { recursive: true });
  copy(from, making);
  try {
    fs.renameSync(making, to);
  } catch {
    // (another process made it first)
    fs.rmSync(making, { recursive: true, force: true });
  }
  for (const other of uses) mirrorPackage(cacheDir, other);
}

used by