shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
GGfpc 2020-12-26T14:28:23.128600Z

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

oconn 2020-12-26T14:32:38.130Z

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

2020-12-26T14:33:14.130500Z

☝️ 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.

GGfpc 2020-12-26T15:07:09.130700Z

that's perfect, thanks!

2020-12-26T15:32:51.131300Z

I use deps.edn and aliases with a namespace containing a map with all the variables.

oconn 2020-12-26T15:38:38.131500Z

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?

thheller 2020-12-26T17:18:08.132600Z

@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

thheller 2020-12-26T17:18:26.132900Z

:modules does nothing in :bootstrap

thheller 2020-12-26T17:18:57.133200Z

you need the browser build and the bootstrap build. separate.

oconn 2020-12-26T19:21:15.140200Z

@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?

2020-12-26T19:59:05.141300Z

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.

2020-12-26T20:21:30.143200Z

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.

thheller 2020-12-26T20:26:29.144400Z

@oconn no. your :modules control that in your case will be cljs-worker.js in the :output-dir

oconn 2020-12-27T15:51:51.155200Z

@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!

thheller 2020-12-26T20:26:38.144700Z

you load that in the html and then bootstrap init

thheller 2020-12-26T20:27:17.145300Z

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>

thheller 2020-12-26T20:30:20.146300Z

@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

2020-12-26T20:31:40.147100Z

@thheller amazing, was just writing my own extern, but this is magic. Thank you