Fork me on GitHub
Thomas Lisankie02:04:47

Has anyone here tried building a Firefox extension with the library? I know there's quite a bit of overlap when it comes to extensions for both browsers, but what does introduce breaking code is using the Chrome Extension API. All I'm looking to do is build an extension that opens a pop-up window when clicking on the extension's toolbar button and then modifies the web page in the current tab when a button in the pop-up window is clicked. Does something like this use completely different APIs depending on what browser you're in or is it interchangeable between Firefox and Chrome?

Mark Bailey04:04:02

Hello! Does anyone have experience with shadow-cljs and tailwindcss? I am trying to use tailwindcss in a project and I run into problem after problem while trying to make this work!

Gleb Posobin04:04:37

What do you use to painlessly serve frontend in cljs? I saw that there is a zeit now builder for shadow-cljs: Are there any other options?

Chris McCormick04:04:29

@posobin do you mean in production? I use and contribute to this:

👍 1

@posobin if it’s just a static app* then you don’t even need a now builder just build your app with shadow-cljs then deploy your public directory your now.json config can look something like this:

"builds": [
      "src": "public/**",
      "use": "@now/static"
  "routes": [
      "src": "/(.*)",
      "dest": "/public/$1"

👍 1

What are the good practices these days for maintaining a cljs lib using deps ?


not sure if I'm misunderstanding how the code splitting is supposed to work (I'm using figwheel-main with cljs.loader). Shouldn't the module I'm interested in load later with loader/load not be parsed and loaded until I call the load function? It seems that the modules defined are also included in the cljs_base.js which I thought would just be bare minimum to get the loading to work for other modules


@adam678 what do you mean?


@victorbjelkholm429 I'm assuming you've gone through the tutorial and verified that it works? there's enough users that rely on the code splitting stuff that we generally get bug reports if something regressed - we also have basic tests around it.


@dnolen yeah, I mean it works as in everything functions, it just functioned in a way that was unexpected. Here is one example: So I expect the "(println "loaded signup")" to not get called until after I call loader/load :signup but seems it's being called right when either the cljs_base.js file is loaded, or the renderer module, unsure exactly when. Had to drop working on it to proceed with some other stuff but will look into it all deeper this weekend


it's takes about 5 minutes to get through that


note you have to load something


there's is no such thing as just loading base


so the page has to have base + some module


@dnolen sorry if I was unclear in my first message, didn't mean to give the impression that nothing is working. It is working, I can see the messages I should see, they are just happening before I call the loader/load :signup function, which is unexpected (at least that's the expectation from what I had)


I am loading base + the renderer module, but then the signup module is automatically loaded without even calling loader/load


right - that's not right


I understand what you are saying


ended up doing everything from scratch and everything is working as expected in my small reproduction example but not when integrated into a bigger application, so seems I'm doing something wrong there. Will dig deeper but probably user-error in the end


let me do a minimal repo repository and it'll be easier to see (even for myself) what's going on


$ clj --main cljs.main --compile hello-world.core --repl

ClojureScript 1.10.520
cljs.user=> (macroexpand '(cond (< n 0) "negative" (> n 0) "positive" :else "zero"))
(if (< n 0) "negative" (clojure.core/cond (> n 0) "positive" :else "zero"))
cljs.user=> (macroexpand '(if (< n 0) "negative" (clojure.core/cond (> n 0) "positive" :else "zero")))
(if (< n 0) "negative" (clojure.core/cond (> n 0) "positive" :else "zero"))
In the REPL I’m not getting what I expected re: macroexpand


I did a vanilla setup per the Quick Start guide to make sure it wasn’t related to something in the more advanced setup of the project I’m working in.


okay, I see the explanation in the second sentence of the doctring, didn’t notice it at first, my bad: > Note neither macroexpand-1 nor macroexpand expand macros in subforms.


> (swap! session assoc :poll (clj->js(:poll (js->clj js/data :keywordize-keys true)))) Is there a better way to rewrite it? Just trying to extract :poll key from a js JSON and assign it to session atom. js/data is like this(generated via json/write-str): <script> var data = {"poll":{"name":"Test Poll"}}; </script>


(swap! session assoc :poll (goog.object/get js/data "poll"))

👍 1

you’ll want to add goog.object in your namespace requires


Thank you!

Ahmed Hassan19:04:09

How to create an element or node with attributes using Google Closure? Tried gdom/creatElement, gdom/createDom, gdom/setProperties with id attribute. But when I try gdom/getElement or vanilla js getElementById with id, it returns nil.


did you add it to the document?


and why are trying to look it up by id if you already have it?

Ahmed Hassan20:04:45

I looked it up for checking if it's available. By adding to document you mean using append or appendChild?

Quentin Le Guennec20:04:31

Hi, my chrome tab crashes running clojurescript code and I have no idea how to debug it. It does crash when running under figwheel-main but not with cljsbuild.

Quentin Le Guennec20:04:57

Same thing in firefox.

Shako Farhad20:04:22

Anyone know the best way to have a developer flag like

(def dev-environment? true)
in the code?


there's a lot of options. if it's truly related to dev/test I'd be tempted to use a dynamic variable like this


remember the 's, that's a clojure convention


then you change it using binding

Shako Farhad20:04:55

I have a line of code that is needed for dev but will kill performance on prod. So it is basically just for that one line 😛


yeah so I'd probably create an ns called dev and in there (def ^:dynamic *dev-environment?* false) then when running your program in dev you do (binding [dev/*dev-environment*? true] (main-function))

Shako Farhad21:04:37

What about the goog.DEFINE way? Is that basically the same?

Shako Farhad21:04:45

In shadow-cljs you can have these :closure-defines things where goog.DEFINE is used.


sounds cljs specific and possibly even coupled to a specific version of google closure. if it were me I'd use the one that works in both clj/cljs and so is pretty much guaranteed to never stop working


You want to use the goog defines in CLJS, because of dead code elimination:


> goog.DEBUG: The Closure Library uses this for many development features. shadow-cljs automatically sets this to false for release builds.

Shako Farhad08:04:02

Ah! That is cool. Thanks for the headsup!

Peter Tylka22:04:29

Hello, I cannot make MaterialUI theming working. I use reagent and shadow-cljs with node modules. ["@material-ui/styles" :as muistyles] (def MuiThemeProvider (adapt-react-class muistyles/ThemeProvider)) ["@material-ui/core/colors" :as muicolors] ["@material-ui/core/styles" :as mui-core-styles] (def createMuiTheme mui-core-styles/createMuiTheme) (def astroTheme2 #js {:palette {:primary "#00FF00" :secondary muicolors/green}}) (def astroTheme (createMuiTheme astroTheme2)) and later in app root I put [MuiThemeProvider {:theme astroTheme} ... But it does not work. Any ideas?


note that #js is flat and does not convert nested structures. so the astroTheme2 is a js object with a nested CLJS map that mui won't understand. use clj->js for nested stuff instead.

Peter Tylka08:04:36

Thanks, it works now. I also needed to add :main into :primary (def astroTheme2 (clj->js {:palette {:primary {:main "#00FF00"} :secondary muicolors/green}}))


i use material with shadowcljs and helix and it works


I suspect it should work with reagent too 🙂


I don't see anything obviously wrong with what you wrote either.