shadow-cljs

Matthew Davidson 2025-09-26T07:02:55.888949Z

Are hooks fully supported for :browser-test targets? My "preamble" hook, which works for the main app build, causes a weird error when I try to compile its associated :browser-test build.

Matthew Davidson 2025-09-26T07:03:55.842319Z

shadow-cljs - config: /Users/matthew/Code/Swarmify/swarmcdn-browser/shadow-cljs.edn
[:browser-tests] Compiling ...
Prepending preamble
NullPointerException: Cannot invoke "java.io.File.isAbsolute()" because "f" is null
	 (io.clj:417)
	 (io.clj:429)
	 (io.clj:421)
	clojure.core/apply (core.clj:671)
	clojure.core/apply (core.clj:662)
	shadow.build.data/output-file (data.clj:284)
	shadow.build.data/output-file (data.clj:279)
	shadow.build.targets.browser/flush-unoptimized/fn--6003/fn--6005 (browser.clj:683)
	clojure.lang.PersistentVector.reduce (PersistentVector.java:418)
	clojure.core/reduce (core.clj:6964)
	clojure.core/reduce (core.clj:6947)
	shadow.build.targets.browser/flush-unoptimized/fn--6003 (browser.clj:681)
	shadow.build.targets.browser/flush-unoptimized (browser.clj:678)
	shadow.build.targets.browser/flush-unoptimized (browser.clj:664)
	shadow.build.targets.browser/flush (browser.clj:698)
	shadow.build.targets.browser/flush (browser.clj:687)
	shadow.build.targets.browser/process (browser.clj:790)
	shadow.build.targets.browser/process (browser.clj:768)
	shadow.build.targets.browser-test/process (browser_test.clj:94)
	shadow.build.targets.browser-test/process (browser_test.clj:84)
	clojure.lang.Var.invoke (Var.java:386)
	shadow.build/process-stage/fn--14330 (build.clj:163)
	shadow.build/process-stage (build.clj:160)
	shadow.build/process-stage (build.clj:152)
	shadow.build/flush (build.clj:553)
	shadow.build/flush (build.clj:547)
	shadow.cljs.devtools.api/compile* (api.clj:298)
	shadow.cljs.devtools.api/compile* (api.clj:293)
	shadow.cljs.devtools.cli-actual/do-build-command (cli_actual.clj:34)
	shadow.cljs.devtools.cli-actual/do-build-command (cli_actual.clj:25)
	shadow.cljs.devtools.cli-actual/do-build-commands (cli_actual.clj:49)
	shadow.cljs.devtools.cli-actual/do-build-commands (cli_actual.clj:38)
	shadow.cljs.devtools.cli-actual/main/body-fn--16691--auto----17355 (cli_actual.clj:166)
	shadow.cljs.devtools.cli-actual/main (cli_actual.clj:165)
	shadow.cljs.devtools.cli-actual/main (cli_actual.clj:132)
	clojure.core/apply (core.clj:671)
	clojure.core/apply (core.clj:662)
	shadow.cljs.devtools.cli-actual/-main (cli_actual.clj:219)
	shadow.cljs.devtools.cli-actual/-main (cli_actual.clj:217)
	clojure.lang.Var.applyTo (Var.java:707)
	clojure.core/apply (core.clj:667)
	clojure.core/apply (core.clj:662)
	shadow.cljs.devtools.cli/-main (cli.clj:75)
	shadow.cljs.devtools.cli/-main (cli.clj:67)
	clojure.lang.Var.applyTo (Var.java:707)
	clojure.core/apply (core.clj:667)
	clojure.main/main-opt (main.clj:515)
	clojure.main/main-opt (main.clj:511)
	clojure.main/main (main.clj:665)
	clojure.main/main (main.clj:617)
	clojure.lang.Var.applyTo (Var.java:707)
	clojure.main.main (main.java:40)

Matthew Davidson 2025-09-26T07:04:22.081759Z

The preamble-hook:

(ns shadow.hooks
  (:require [ :as io]))

(def preamble
  (apply str
         "// Swarmify preamble start\n\n"
         (slurp (io/resource "public/javascript/video.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.ads.js"))
         "\n"
         (slurp (io/resource "public/javascript/swarm.js"))
         "\n"
         (slurp (io/resource "public/javascript/swarm-hex-button.js"))
         "\n"
         (slurp (io/resource "public/javascript/swarm-watermark.js"))
         "\n"
         (slurp (io/resource "public/javascript/swarm-disabled.js"))
         "\n"
         (slurp (io/resource "public/javascript/swarm-health.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.watermark.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.ima.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.related.videos.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.ga.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.thumbnails.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.resolutions.js"))
         "\n"
         (slurp (io/resource "public/javascript/youtube.js"))
         "\n"
         (slurp (io/resource "public/javascript/vjs.vimeo.js"))
         "\n"
         (slurp (io/resource "public/javascript/videojs.progressTime.js"))
         "\n"
         (slurp (io/resource "public/javascript/fake-xml-http-request.js"))
         "\n\n// Swarmify preamble end\n\n"))

(defn preamble-hook
  {:shadow.build/stage :configure}
  [build-state & args]
  (println "Prepending preamble")
  ;;   (prn build-state)
  (let [stage (:shadow.build/stage build-state)]
    (-> build-state
        (assoc-in [:shadow.build.modules/config :swarmcdn :prepend] preamble))))

thheller 2025-09-26T10:20:21.624999Z

:browser-test is using :browser under the hood. so can't see a reason why that wouldn't work

thheller 2025-09-26T10:20:52.763509Z

I suspect that :output-dir or something is missing, sind browser test normally only uses :test-dir

thheller 2025-09-26T10:21:35.452979Z

can't check right now though

Matthew Davidson 2025-09-26T10:21:48.910649Z

:output-dir IS missing... I thought we were supposed to define :test-dir instead

Matthew Davidson 2025-09-26T10:22:14.996319Z

e.g.:

:browser-tests
  {:target :browser-test
   :test-dir  "out/browser-tests"
   :build-hooks [(shadow.hooks/preamble-hook)]}

thheller 2025-09-26T10:22:35.534469Z

yes, normally not needed. I just suspect that this is triggering some code path that expects it

thheller 2025-09-26T10:22:48.088509Z

just a guess. no clue, can check later.

Matthew Davidson 2025-09-26T10:22:58.925679Z

ok, thx

Matthew Davidson 2025-09-26T10:23:28.516189Z

Hmm, should output dir be the same as test-dir, or different?

thheller 2025-09-26T10:24:04.299379Z

I'm guessing without looking at any code. don't pay any attention to it. I will verify later.

Matthew Davidson 2025-09-26T10:24:20.234049Z

OK. LMK how I can help