Skip to content

Builds read cljs.core's analysis cache for the copy they compile: restored output keeps its Closure Library modules - #22

Merged
k7d merged 1 commit into
WhimsicalCode:mainfrom
storrito:core-cache-goog-libs
Nov 2, 2026
Merged

k7d merged 1 commit into
WhimsicalCode:mainfrom
storrito:core-cache-goog-libs

Conversation

@maxweber

@maxweber maxweber commented Nov 2, 2026

Copy link
Copy Markdown

The problem

In a project depending on the compiler's artifact (cljf 0.12.12 and 0.12.13 from npm), a cold build whose cljs.core output comes from the per-user cache (cljs-core/, since 0.12.12) writes no goog-lib/ns/goog.math.Integer.js and no goog.Uri.js, the two Closure Library modules only cljs.core imports. The output then fails to load:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '…/target/test/goog-lib/ns/goog.math.Integer.js' imported from …/target/test/cljs/core.js

Seen on every build after rm -rf target in a checkout that had built once before (the first build of a fresh checkout has no cache entry yet and compiles cljs.core, so it works; an incremental build keeps the modules of the build before). CLJF_CACHE_DIR=$(mktemp -d) or :core-cache false works around it.

The cause

cljf.esm/compile-ns loaded cljs.core's analysis through with-core-cljs when its output was up to date. That analyzes the classpath's cljs/core.cljs, the jar's entry, whose modification time differs from the analysis cache written for the copy in the output directory (by the compile of the output, or by restore-core!). requires-analysis? compares the two times, so the cache was judged stale and the source analyzed again, on every build, and the cache rewritten without :cljf.esm/goog-libs, which only compiling records (esm-goog-lib!). install-goog-libs then had cljs.core's modules only when something else used them too (goog.math.Long through transit, goog.string.StringBuffer).

In this repository's own tests cljs/core.cljs is a plain file, so the times matched and nothing showed.

The change

  • compile-ns reads cljs.core's analysis from source-file's cache like every other namespace's (ana/analyze-file source-file), no with-core-cljs: the copy's time is the cache's. An up to date build no longer analyzes cljs.core's source either.
  • esm_build_tests/restores-core-with-its-closure-libraries: cljs/core.cljs served from a jar through a child-first context class loader (it hides the parent's copy from check-classpath! too), cljf.main/cache-dir redefined to a directory of its own, two builds with the output deleted in between. Without the fix only its last assertions fail (the restored build lacks goog.math.Integer.js); with it the suite passes.
  • A [Next] changelog entry under Fixed.

Checked

  • script/test-esm: the build and REPL tests (40 tests, 219 assertions) and the runtime suite under Node 26 (670 tests, 21020 assertions), 0 failures, 0 errors.
  • The build tests with the fix stashed: 29 tests, 1 failure, the new test.

The branch is on the storrito fork, as #7 was.

🤖 Generated with Claude Code

… compile, not the jar's entry: a cold build with the output restored from the per-user cache keeps the Closure Library modules only cljs.core imports

cljf.esm/compile-ns loaded cljs.core's analysis through with-core-cljs when
its output was up to date: an analysis of the classpath's cljs/core.cljs,
a jar's entry in a project depending on the compiler's artifact, modified
at another time than the analysis cache written for the copy in the output
directory. So the source was analyzed again on every build and the cache
rewritten without :cljf.esm/goog-libs, which only compiling records. A cold
build with the output restored from the per-user cache (0.12.12) then wrote
no goog-lib/ns/goog.math.Integer.js and goog.Uri.js, and the output failed
to load with ERR_MODULE_NOT_FOUND.

cljs.core's analysis is read from source-file's cache like every other
namespace's: the restore sets the cache's modification time to the copy's,
as a compile does. Up to date builds skip the analysis of cljs.core's
source as well.

The test serves cljs/core.cljs from a jar on a child-first context class
loader and builds twice with a per-user cache of its own
(cljf.main/cache-dir redefined), the output deleted in between.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@k7d
k7d merged commit 69f323b into WhimsicalCode:main Nov 2, 2026
9 checks passed
@k7d

k7d commented Nov 2, 2026

Copy link
Copy Markdown
Member

thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants