Fork me on GitHub

Does shadow-cljs have an API for getting the ClojureScript compiler environment? I'm asking because I'm considering implementing basic ClojureScript auto-completion support from scratch and I believe I need to get a hold of the compiler environment for that.


I found this comment: But that snippet doesn't seem to return the compiler env anymore (unless I messed something up).


(shadow.cljs.devtools.api/compiler-env :the-build)


How did I not find that... facepalm thanks!


watch needs to be running for that to work


Another (maybe too vague) question: I'd like to start a nested REPL using clojure.main/repl that leverages shadow-cljs to evaluate ClojureScript. I'm wondering whether there's any prior art on this sort of thing I ought to be looking at? I tried quickly hacking something together and came up with this:

;; *out-fn* is bound to a function that prints to the socket output stream
(let [out-fn tutkain.repl.runtime.repl/*out-fn*]
    :read clojure.core.server/repl-read ;; add :repl/quit support
    :need-prompt (constantly false) ;; don't want prompt
    :prompt (constantly "") ;; don't want prompt
    ;; eval is code -> value -- cljs-eval is string -> string, so need to pr-str the input form
    :eval #((requiring-resolve 'shadow.cljs.devtools.api/cljs-eval) :app (pr-str %) {})
    :print (fn [{:keys [results out err ns]}]
             (when (seq out) (out-fn {:tag :out :val out}))
             (when (seq err) (out-fn {:tag :err :val err}))
             (run! #(out-fn {:tag :ret :val % :ns ns}) results))))
This seems to work as far as very basic use goes. Does this seem like a reasonable approach? I know that's not enough to have special things like in-ns work -- need to look into that some more.


(shadow.cljs.devtools.api/repl :the-build {:prompt false})


if you want more control over what the REPL does you could use what it internally uses


but would be better to make an issue for it with a proper description so I can add an actual API fn for it


Yeah, that's what I was looking for. Thanks! I'll dive into it and make an issue if something turns up.


digging into internals too much is not recommended because I might break it at any point 😛


One more: if I do this:

(when file
    (let [{:keys [results err]} ((requiring-resolve 'shadow.cljs.devtools.api/cljs-eval)
                                 (format "(cljs.core/load-file \"%s\" %s)" file code) {})]
      (when err
        (out-fn (response-for message {:tag :err :val err}))
        (run! #(out-fn (response-for message {:tag :ret :val %})) results))))
And the code is a ClojureScript namespace that uses an auto-qualified keyword like ::db/reset, I get this error:
repl-input.cljs [line 23, col 38] Invalid keyword: ::db/reset.
The namespace has a require like this: [app.client.db :as db]. Are auto-qualified keywords not supported? This might also be more of a general ClojureScript question, but if I've understood correctly, shadow-cljs implements its own load-file kind of thing.


it is much easier for me to answer stuff if you show the actual REPL code


shadow-cljs node-repl or browser-repl and then the actual command


I don't know if you are escaping the strings properly etc


the aliases should work just fine, assuming they actually exist


Oh, string escaping is a good point. Gotta double-check that.


They do exist, the code itself works. But yeah, I'll come back with a better repro if it's something else than string escapes.


load-file also only take one argument?


Oh, that's right. I must've gotten it mixed up... good catch, thanks. :thumbsup::skin-tone-2:


Is there a way to generate the "build report" html file when doing a proper release? Right now it seems that it takes as much time to do the release as it takes to generate the report. Would be nice to cut our CI times in half.


not currently no. it could in theory but currently it is separate since it changes a bunch of stuff in the config to make things easier. needs to be able to access source maps and stuff


(which are not enabled by default for release for example)


Makes sense. I've enabled source maps in release mode now (I'm trying to integrate Sentry), but I guess it's not that simple.


should be simple but no clue 🙂

Alys Brooks20:04:16

I've tried enabling the babel integration to compile my output for IE11, but it doesn't seem to be working. Here's my shadow-cljs.edn:

{:builds {:main 
          {:js-options {:babel-preset-config {:ie 11}}

Alys Brooks20:04:07

I tried enabling a verbose build log, and babel doesn't seem to be anywhere.


babel is not applied to all JS sources, the more reliable option is :compiler-options {:output-feature-set :es3}


what exactly doesn't work in IE11? I mean typically es5 should be fine for that?

Alys Brooks21:04:22

I think the issue is that IE11 doesn't support String.includes . The code is for a client and not open source, so I'd have to see if the error is in the application code or one of the libraries we're using.


you can try setting :compiler-options {:force-library-injection #{"es6/string/includes"}} in your build config


that will inject the polyfill if needed

Alys Brooks22:04:10

I fixed one of the issues upstream with glögi, but now URLSearchParams is causing a problem.


did you try a release build? unless you are on version 2.12.5 the :force-library-injection only works for release builds

Alys Brooks18:04:05

Oh, that works now, thanks! I'm not sure there's a Google Closure polyfill for URLSearchParams, though.


you can always use to get whatever standard polyfills you need for IE

Alys Brooks19:04:08

That looks like a good resource! I have seen references to babel, but it seems like it might lag behind in terms of polyfill support.


babel doesn't lag behind. babel isn't used.


it has one specific purpose in shadow-cljs but that is not polyfilling. in fact we don't want it to polyfill at all and I'll likely remove that aspect of it completely

Alys Brooks19:04:54

I think I'm going to use goog.uri instead of (Probably why Google Closure doesn't have a polyfill for URLSearchParams)

Alys Brooks19:04:16

Would you be interested in a PR adding documentation around :force-library-injection? It seems like it's a fallback/last resort, but the documentation could definitely note that.


under normal circumstances it is never required to set it


just under some weird circumstances that I have not been able to reproduce it needs to be manually added


sure it would be worth documenting but I'd rather identify why its not detected properly 😉

Alys Brooks19:04:51

Makes sense. I can try to reproduce with a minimal sample project, if that would help.

Alys Brooks20:04:21

You might not be surprised to hear that I'm not having a lot of luck reproducing in a simpler sample project. I thought maybe something about Glögi was confusing it or perhaps Glögi plus separate modules, but both of those are working fine. I'll keep trying today.


yeah it has proven difficult to reproduce 😛

Alys Brooks21:04:40

I'm not having any luck with that either. 😕 . I'm putting it in :builds . It also looks like the issue is coming from one of the libraries I'm using. I don't think that should make a difference, as it's also ClojureScript that would need to be compiled, though?

Alys Brooks22:04:42

The build log does say it's generating polyfills