Hello. Continuing the discussion from https://clojurians.slack.com/archives/C06MAR553/p1758141056002619 here. Specifically about the runtime description label. Today we have client-id and either desc or user-agant, afaiu. desc and user-agent do not distinguish very well between different runtime instances. I have the app running in Brave, Chrome, and inside VS Code’s simple-browser, and they all display the same user agent. And someone like @hoppy has it running on a lot of rapberry pis at once, all with the same desc (as long as they have the same node version running). I really have no idea what could be done about it, but want to at least explore it together with you people.
Is there a solution to the lack of :preamble support? I've inherited a very old cljs code base that uses it with lein-cljsbuild, and I'm in the process of modernizing it with shadow.
The production build uses preamble to prepend a dozen plain .js files, half of which are old enough that they're not on npm and don't even use modules; they just set a bunch of globals we refer to.
I saw prepend-js, but these are definitely not GCC compatible. prepend looks like what I want, but it only takes strings.
I found https://clojurians.slack.com/archives/C6N245JGG/p1568024913425000, is that still recommended, or is there something I should do with hooks instead (maybe :optimize-finish)?
I'd prefer to switch to shadow, get it working as-is, and only then start updating libraries, if possible.
Thanks for any suggestions!
I ended up adding a preamble hook for both dev and release builds, as too much of the existing setup expects one concatenated file, since that's what we deliver to clients, anyway. Trying to separate them just makes it harder to test the builds the same way. In case anyone needs it, here's what we did:
(ns shadow.hooks
(:require [clojure.java.io :as io]))
(def preamble
(apply str
"// Preamble start\n\n"
(slurp (io/resource "this"))
"\n"
(slurp (io/resource "that"))
...
"\n\n// Preamble end\n\n"))
(defn preamble-hook
{:shadow.build/stage :configure}
[build-state & args]
(println "Prepending preamble")
(let [stage (:shadow.build/stage build-state)]
(-> build-state
(assoc-in [:shadow.build.modules/config :your-module-name :prepend] preamble))))
;; in shadow-cljs.edn:
{...
:builds {:your-module-name {:build-hooks [(shadow.hooks/preamble-hook)]
...Any further thoughts? Sorry to bug you.
(-> (shadow/get-build-config :your-build) (update-in [:modules :main] assoc :prepend (slurp "whatever.doc")) (shadow/release*)) seems like the best option?
for local testing I'd just use a separate script tag and for release just prepend it
you can use the above via https://shadow-cljs.github.io/docs/UsersGuide.html#clj-run
Thanks! You recommend the above over a hook fn?
(defn release []
(-> (shadow/get-build-config :your-build)
(update-in [:modules :main] assoc :prepend (slurp "whatever.doc"))
(shadow/release*)))yes
Got it. Will try this. Thank you very much for your help
seems like it would be easier to just leave the extra .js files as they are, or concatenated together into one .js file. and then just add an extra script tag to your html to load it? or any particular reason shadow even needs to know about it?
@thheller Sorry, to clarify, we produce one js artifact for clients to install on their own websites. We don't control the pages it's installed on. And realistically, I don't think I can convince them all to add another dozen <script> tags 😄
I also found a suggestion to do something like (assoc-in build-state [:shadow.build.modules/config :main :prepend] licenses)
I ended up getting the @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner node modules (which are part of https://github.com/aws/aws-sdk-js-v3) to compile with ShadowCLJS by adding
:js-options {:entry-keys ["module" "browser" "main"]}
as per https://shadow-cljs.github.io/docs/UsersGuide.html#js-entry-keysStill not sure I understand what's going on. But it works 🙂
It did however reduce my bundle size from 10MB to 1.8MB
you probably also want to add :export-conditions ["module" "import" "browser" "require" "default"] to the :js-options map. that ensures packages with "exports" also take the esm files, since that is pretty common these days
Ah right, saw it here in Slack but couldn’t find it in the Shadow-CLJS guide
Pretty sure this could be ported to Cljs. Would probably be even smaller: https://github.com/jacobemcken/aws-simple-sign/blob/main/src/aws_simple_sign/core.clj
:compiler-options {:source-map true} is the default in shadow right? I do see generated .map files but no mention of //# sourceMappingURL in my module .js file
its the default for dev builds, release builds no
The release build still produces maps but doesn’t link them or so?
if you have the build-report hook active yes, because thats working off source maps it enables them but doesn't link them
Ah now I got it then, thanks!
Is there a disadvantage of including source maps for release builds? Does a browser greedily download them?
source maps contain all the sources. so if you don't mind users getting access to your sources then no. browsers only download with devtools open.
That’s fine, it’s open source anyway. Thanks!