Hello! Is there anyway I can set up an environment variable that is replaced at build time? For instance, I want my source code to have an IP address pointing to localhost, but when I release a build I want it to be replaced with my server's address
I use closure-defines
for this kind of configuration. https://clojurescript.org/reference/compiler-options#closure-defines & goog-define
https://cljs.github.io/api/cljs.core/goog-define where the second argument would be your default localhost address
☝️ Same. There's a section on how to use them in the user guide, too: https://shadow-cljs.github.io/docs/UsersGuide.html#closure-defines.
that's perfect, thanks!
I use deps.edn and aliases with a namespace containing a map with all the variables.
Hi, I’m looking to use shadow-cljs to self-host a cljs project in a web worker. I feel like I’m close and probably configuring my build wrong…
In my shadow-cljs.edn
config I have my cljs worker build configured like this;
{:builds {:cljs-worker {:target :browser
:output-dir "resources/public/js"
:asset-path "/js"
:compiler-options {:optimizations :simple}
:modules {:cljs-worker-base {:entries [shadow.cljs.bootstrap.env]}
:cljs-worker {:init-fn workers.cljs.core/init!
:depends-on #{:cljs-worker-base}
:web-worker true}}}
In workers.cljs.core
i’ve got;
(ns workers.cljs.core
(:require [cljs.env :as env]
[cljs.js :as cljs]
[shadow.cljs.bootstrap.browser :as boot]))
(defn- process-response
[{:keys [error value] :as result}]
(when (some? error)
(js/console.log "ERROR")
(js/console.error error))
(when (some? value)
(js/console.log "VALUE")
(js/console.log value))
result)
(defonce compile-state-ref (env/default-compiler-env))
(defn evaluate [code]
(cljs/eval-str
compile-state-ref
code
nil
{:eval cljs/js-eval
:load (partial boot/load compile-state-ref)}
process-response))
(defn init! []
(boot/init compile-state-ref {:path "/js"} #(evaluate "(+ 1 1)")))
which was inspired by https://code.thheller.com/blog/shadow-cljs/2017/10/14/bootstrap-support.html - Configured this way results in the following error;
failed to download boostrap file:/js/index.transit.json
It seems this file is only generated when setting the target to bootstrap
?
Changing my config to more closely match the blog post generates index.transit.json
but does not build modules.
:cljs-worker
{:target :bootstrap
:output-dir "resources/public/js"
:asset-path "/js"
:compiler-options {:optimizations :simple}
:modules {:cljs-worker-base {:entries [shadow.cljs.bootstrap.env]}
:cljs-worker {:entries [cljs.js]
:exclude #{cljs.js}
:macros []
:init-fn workers.cljs.core/init!
:depends-on #{:cljs-worker-base}
:web-worker true}}}
Is there a configuration that will allow me to build a worker supporting self-hosted cljs?@oconn failed to download boostrap file:/js/index.transit.json
looks like you are trying to do this directly from the filesystem? that won't work, you need a http server. you can use :dev-http
:modules
does nothing in :bootstrap
you need the browser build and the bootstrap build. separate.
@thheller - Looks like index.transit.json
is loaded directly in shadow.cljs.bootstrap.browser/init
.
I’m running a dev server using;
:devtools {:http-root "resources/public"
:http-port 9000
:preloads [shadow.remote.runtime.cljs.browser]}
I changed my bootstrap build to
:cljs-worker
{:target :bootstrap
:output-dir "resources/public/js/workers/cljs"
:compiler-options {:optimizations :simple}
:entries [cljs.js workers.cljs.core]
:exclude #{cljs.js}
:macros []}
and that is compiling everything under the output-dir
but I’m not sure what js file I’m supposed to load into my web worker?
Taking a looking at the bootstrap-support
build in shadow-cljs
’s shadow-cljs.edn
config, it outputs to out/demo-selfhost/public/bootstrap
. The index file in that dir loads <script src="/worker/js/base.js"></script>
- Is there supposed to be a base.js
file in the output?I am running into something interesting, I have to access the :cause field of an cljs.core/ExceptionInfo and noticed it's being mangled by an release build. Now figuring out how to protect against the mangling.
The cause I want to read out is build here in this async.interop. Advanced compilation mangles the class name, and the cause field, making it inaccessible for ex-cause.
@oconn no. your :modules
control that in your case will be cljs-worker.js
in the :output-dir
@thheller Thanks for pointing me in the right direction! I was loading my web worker using a relative path. Also didn’t know I needed two separate builds for self-hosted cljs. Thanks again!
you load that in the html and then bootstrap init
again failed to download boostrap file:/js/index.transit.json
this error suggests that you just loaded the index.html
directly from the filesystem in the browser instead of <http://localhost:9000>
@deplect in general if something gets mangled that you don't want mangled you need externs. see https://shadow-cljs.github.io/docs/UsersGuide.html#_simplified_externs just add cause
one line to preserve it
@thheller amazing, was just writing my own extern, but this is magic. Thank you