Fork me on GitHub
#shadow-cljs
<
2019-05-18
>
carkh01:05:49

I'm trying to make a chrome extension, there is many moving parts, so i output the extension itself to resources/public/js/extension and set the output-dir for the background script in resources/public/js/extension/background. Compilation works, then I add the extension to chrome targeting resources/public/js/extension (where my extension manifest is). The trouble is that now chrome is looking for the modules with /resources/ as root rather than resources/public/js/extension So how can i ask shadowcljs (or maybe the clojurescript compiler?) to root the js lookup in resources/public/js/extension` ?

carkh01:05:48

In other words, right now chrome tries to load but i want it to try loading

carkh01:05:06

ah got it :asset-path "/background"

carkh02:05:04

now for hot code reloading ...shadowcljs is trying to open a websocket at .... which of course doesn't work, how can i tell it to use my already running server at ?

carkh02:05:01

ah for posterity : :devtools-url "" in :devtools key of shadow-cljs.edn

thheller08:05:05

@carkh its not documented well but shadow-cljs can build chrome-extension directly which fixes all those issues https://github.com/thheller/shadow-cljs/issues/279

carkh08:05:08

oh wow, i've been worrying about the module thing, but didn't investigate that yet

carkh08:05:49

didn't have any trouble with switching repls though

carkh08:05:31

looking at the issue, you have browser-action and content-script, is it also possible specify the options-page ?

carkh08:05:11

that's another compilation that might benefit form modules

thheller08:05:37

it probably is yeah

thheller08:05:00

haven't looked at it in a while but I think I covered all possible built targets

carkh08:05:42

very nice, i'll try to switch to this new workflow and maybe tell you how it goes if you'd like that

thheller08:05:19

since its all built on modules you can pretty much build everything

thheller08:05:43

since all that really matters is how the code gets loaded

thheller08:05:24

opts pages looks the same as the other html driven options

thheller08:05:18

so you can probably set :output-type :chrome/page-action for the module

thheller08:05:32

sorry ... this stuff really needs docs

carkh08:05:52

don't be sorry, already awesome that this exists at all

thheller08:05:27

here is one extension that uses this stuff maybe that helps in some way https://github.com/fulcrologic/fulcro-inspect/blob/master/shells/chrome/manifest.edn

carkh08:05:52

hah i'm using it, and actually am using fulcro for the options page

🔥 4
nickmbailey17:05:26

is using eval from the shadow-cljs repl supported?

nickmbailey17:05:32

[0:0]~cljs.user=> (eval '(+ 1 2))
Error: cljs.core/*eval* not bound

nickmbailey17:05:39

is there some other setup i need to do

carkh17:05:25

@nickmbailey afaik there is no eval with clojurescript

carkh17:05:06

self hosted clojurescript probably has it if necessary

thheller17:05:24

@nickmbailey eval in CLJS requires using the self-hosted compiler. shadow-cljs does support building everything you need for that but doesn't run it itself. see https://code.thheller.com/blog/shadow-cljs/2017/10/14/bootstrap-support.html

carkh18:05:36

@thheller so i switched to the :chrome-extension target as we discussed. And I hit the repl switching problem. I have several running javascript instances under the single chrome-extension build, and i can only invoke the repl on a per build basis... any workaround i should be aware of ?

thheller18:05:07

if you are using nrepl not really no

carkh18:05:17

mhh that's a problem, no auto-completion in cider when in the wrong repl ... too bad i like that whole build target thingie =(

carkh18:05:30

thanks anyways !

thheller18:05:48

auto completion should work. I don't think that calls eval?

carkh18:05:35

i don't quite know why but it doesn't ... when in a build's repl that doesn't "link" to the current buffer no auto-complete in cider

carkh18:05:38

probably uses some nrepl magic to get the live state

carkh18:05:08

very much not my expertise =)

thheller18:05:20

that all should work since it shouldn't try to eval

thheller18:05:36

eval is the only issue since with multiple runtimes it is not clear how to do that consistently

thheller18:05:53

but I know nothing about cider so can't help much

carkh18:05:16

no big deal i'll go back to the old way which was working fine, in the meantime i got better organisation out of this escapade

carkh18:05:39

too bad i'll be losing the modularisation, maybe just use the chrome-extension target for release

nickmbailey18:05:17

is there a way to dynamically define vars in clojurescript?

nickmbailey18:05:37

i'm using intern in a macro in clojure but thats not available in clojurescript

nickmbailey18:05:47

(was previously playing with eval, hence the earlier question)

thheller18:05:02

dynamically as in a macro yes, at runtime no

nickmbailey18:05:14

well it should be fine to happen at compile time but eval wasn't working so i switched to intern which lets it happen at runtime

nickmbailey18:05:28

so i guess i can switch to self hosted clojurescript

thheller18:05:16

what are you trying to do exactly?

thheller18:05:40

typically you should just have the macro emit (def ...) forms

thheller18:05:26

the super dynamic clojure style Var creation via actual Var calls will not work even in self-hosted CLJS since there are no vars at runtime

nickmbailey18:05:54

i'm making a macro that makes builder fns for plumatic/schema map keys so:

(crazy-macro foo {:a Int})
creates a var like
foo-a
. the problem is i want it to also support
(crazy-macro bar (merge foo {:b Int}))
which means i need the evaluated version of the map

nickmbailey18:05:58

in regular clojure just eval'ing the form works, or using intern to inject the vars at runtime also works

thheller18:05:45

why does it create vars?

nickmbailey18:05:09

well they are builder functions

nickmbailey18:05:22

it creates vars via defn

thheller18:05:46

what does that mean? 🙂

thheller18:05:55

builder functions sound like OOP mess to me?

nickmbailey18:05:08

heh i don't disagree with that

nickmbailey18:05:31

its a bit of a crazy idea

thheller18:05:22

if you can stomach adding several megabytes of JS to your build I guess self-host is something you can try

thheller18:05:30

but otherwise I would probably look for better solutions

nickmbailey18:05:51

yeah i'll probably abandon this for clojurescript for now heh

nickmbailey20:05:15

it seems like when shadow-cljs is compiling a .cljc file and it runs into a reader conditional it picks the ":clj" option

thheller20:05:55

if you are loading the ns as a macro yes

nickmbailey20:05:23

hmm why is that?

thheller20:05:12

hmm? its the same as anywhere else?

thheller20:05:27

macros in CLJS are written in Clojure

nickmbailey20:05:06

right, i'm trying to make the macro do nothing in clojurescript

thheller20:05:56

any particular reason you are writing that in a .cljc file?

thheller20:05:17

.cljc is kinda mind bending when it comes to macros and stuff so I would recommend avoiding it as much as possible

thheller20:05:42

you can't use reader conditionals to decide what code a macro should emit

nickmbailey20:05:13

hmm well i'm trying to use reader conditionals around the defmacro call completely

nickmbailey20:05:33

#?(:cljs (defmacro...) :clj (defmacro...)

thheller20:05:42

yeah thats not gonna work 🙂

thheller20:05:53

that would be for self-hosted macros

nickmbailey20:05:27

ok but i should be fine if i just split into clj and cljs files?

thheller20:05:47

the trick commonly used in macros that should emit different code for CLJ or CLJS is checking the &env

thheller20:05:10

#?(:clj (defmacro foo [& args] (if (:ns &env) :cljs :clj)))

thheller20:05:13

so (foo 123) used in CLJS will end up just returning :cljs

thheller20:05:22

and :clj if called in CLJ

thheller20:05:07

you need (ns the.ns #?(:cljs (:require-macros [the.ns]))) self-require for macros

nickmbailey20:05:35

hmm i'm using :refer-macros

nickmbailey20:05:41

is that the same?

thheller20:05:09

well yes ... but don't do that. this way is much simpler.

thheller20:05:52

lets others using the.ns completely skip worrying about macros and just use them as you would in CLJ

nickmbailey20:05:07

ah i put that in the file where the macro is defined

thheller20:05:10

so (ns (:require [the.ns :as x])) (x/foo) works

nickmbailey20:05:20

@thheller that got me up and running, thanks for the help!

nickmbailey20:05:26

and more generally thanks for shadow-cljs heh