diff --git a/packages/compiler/src/index.ts b/packages/compiler/src/index.ts index 474d61e46..472f5cd14 100644 --- a/packages/compiler/src/index.ts +++ b/packages/compiler/src/index.ts @@ -1376,7 +1376,7 @@ async function compileTracked( const helperObjectRoute = opts.nativeProgramObject === true || usesPrecompiledRuntimePack(opts, "llvm"); // Calls into Node record the libnode pack, keyed by its manifest (node-islands/libnode.ts). - const libnodeKey = libnodeCacheKey(opts.libnode, process.env, dirname(entryPath)); + const libnodeKey = libnodeCacheKey(opts.libnode); const routeOptions: Omit< EarlyExecutableCacheOptions, "implementation" | "implementationDependencies" | "nativeEnvironment" diff --git a/packages/compiler/src/node-islands/libnode-pack.ts b/packages/compiler/src/node-islands/libnode-pack.ts index fb6669cac..a43fde48e 100644 --- a/packages/compiler/src/node-islands/libnode-pack.ts +++ b/packages/compiler/src/node-islands/libnode-pack.ts @@ -186,12 +186,13 @@ export function readLibnodePack( return { root, manifest }; } -/** The nearest `node_modules/` directory walking up from `from`. */ +/** The nearest `node_modules/` directory with a built pack (a + * manifest.json) walking up from `from`. */ function findInstalled(name: string, from: string): string | null { let dir = resolve(from); for (;;) { const candidate = join(dir, "node_modules", name); - if (existsSync(join(candidate, "package.json"))) return candidate; + if (existsSync(join(candidate, "manifest.json"))) return candidate; const parent = dirname(dir); if (parent === dir) return null; dir = parent; @@ -200,7 +201,9 @@ function findInstalled(name: string, from: string): string | null { function resolveNextToCompiler(name: string): string | null { try { - return dirname(createRequire(import.meta.url).resolve(`${name}/package.json`)); + const dir = dirname(createRequire(import.meta.url).resolve(`${name}/package.json`)); + // An unbuilt workspace package is not a pack. + return existsSync(join(dir, "manifest.json")) ? dir : null; } catch { return null; } diff --git a/packages/compiler/src/node-islands/libnode.test.ts b/packages/compiler/src/node-islands/libnode.test.ts index c62783a47..d6ca4bf83 100644 --- a/packages/compiler/src/node-islands/libnode.test.ts +++ b/packages/compiler/src/node-islands/libnode.test.ts @@ -93,13 +93,8 @@ describe("the recorded libnode pack", () => { }); describe("the libnode pack in an executable's cache key", () => { - test("is absent without --libnode, SCRIPTC_LIBNODE or an installed pack", () => { - const installed = findInstalledLibnodePack({ - targetName: hostLibnodeTarget(), - projectDir: "/nonexistent", - }); - if (installed === null) expect(libnodeCacheKey(undefined, {}, "/nonexistent")).toBeUndefined(); - else expect(libnodeCacheKey(undefined, {}, "/nonexistent")).toContain(installed); + test("is absent without --libnode or SCRIPTC_LIBNODE", () => { + expect(libnodeCacheKey(undefined, {})).toBeUndefined(); }); test("changes when the pack in the same directory is upgraded", () => { diff --git a/packages/compiler/src/node-islands/libnode.ts b/packages/compiler/src/node-islands/libnode.ts index be6eaff65..cb4e7e21c 100644 --- a/packages/compiler/src/node-islands/libnode.ts +++ b/packages/compiler/src/node-islands/libnode.ts @@ -119,24 +119,20 @@ export function libnodeRecord( } /** The part of an executable's cache key that names its libnode pack, or - * undefined when neither --libnode nor SCRIPTC_LIBNODE is set and no pack - * is installed. It holds the option, the pack directory and a digest of the - * pack's manifest.json, so that a pack upgraded in place (another Node - * version, bridge ABI or file list) gives cached executables a new key - * instead of their old record. */ + * undefined when neither --libnode nor SCRIPTC_LIBNODE is set. It holds the + * option, the pack directory and a digest of the pack's manifest.json, so + * that a pack upgraded in place (another Node version, bridge ABI or file + * list) gives cached executables a new key instead of their old record. + * An installed @scriptc/libnode- pack needs no part: it versions + * in lockstep with the compiler, whose version every key already holds, so + * the bootstrap's routed cache keeps serving builds where one is installed. */ export function libnodeCacheKey( option: string | undefined, env: NodeJS.ProcessEnv = process.env, - projectDir: string = process.cwd(), ): string | undefined { const fromEnv = env["SCRIPTC_LIBNODE"]; - const installed = - option === undefined && fromEnv === undefined - ? findInstalledLibnodePack({ targetName: hostLibnodeTarget(), projectDir }) - : null; - if (option === undefined && fromEnv === undefined && installed === null) return undefined; - const source = - installed ?? (option !== undefined && option !== "beside" ? option : (fromEnv ?? "")); + if (option === undefined && fromEnv === undefined) return undefined; + const source = option !== undefined && option !== "beside" ? option : (fromEnv ?? ""); let manifest = "none"; if (isAbsolute(source)) { try {