Fork me on GitHub

hello folks, i inherited a cljs code base that is built using figwheel. i recently ran into an issue where the JS output file would work fine on my local development machine but have all these strange broken buttons on my QA server. I noticed that the difference between the two JS output files was that the one i was testing with had optimizations set to none but the QA server was using optimizations advanced. so, the next reasonable thing for me was to try building with advanced optimizations and test on my local dev machine. the build works but i run into an error on the browser:

goog.require could not find: env.web.config
which is really weird because when i enable verbose logging, I see figwheel acknowledges the presence of the file.. but does not compile it?
Analyzing env/dev/env/web/config.cljs
Compiling ....../parser.cljs, elapsed time: 917.850835 msecs
The figwheel build settings look good to me and I think I've set the source paths correctly:
{:id "web"
                 :source-paths ["src" "env/dev"]
                 :compiler{:main ...
                           :output-to "resources/public/main.js"
                           :output-dir "resources/public/js"
                           :optimizations :whitespace
                           :parallel-build true
                           :compiler-stats true
                           :verbose true
                           :externs ["resources/lib/ext/webview-bridge.ext.js"]
                           :source-map "resources/public/"
                           :source-map-timestamp true}}
Any idea why the compiler would skip the file?


Hello everyone, how can I read environment variables in Clojurescript?

Christian Johansen11:11:37

depends on your target

Christian Johansen11:11:35

with node target, just use js/process.env, with a browser target you need to write a macro that reads env variables in Clojure and outputs them to cljs


There's environment variables in the browser? :thinking_face:


environment variable is in system environment variable set using 'export'

Christian Johansen11:11:41

@kristian507 no 🙂 but you could use env variables at compile-time for config etc

Christian Johansen11:11:27

@dsuren I wrote a post a while back about accessing Clojure data in ClojureScript, maybe you’ll find some useful information there:

👍 4
Christian Johansen11:11:13

env vars are simpler, but it is the same basic approach


Is this open ticket still accurate - that cljs.spec data is included in :advanced builds? is there a recommended way to use spec with ClojureScript without impacting build sizes?


I don't recall anything changing there @mhuebert


is cljs.analyzer.api the official analyzer for clojurescript ?


@leonoel Docstring for that namespace: "This is intended to be a stable api for those who need programmatic access to the analyzer."


good. I don't understand why the js* special form is exposed in analyzed output. How is it supposed to be handled ?


I am especially confused about your comment here implying that evaluating js* args is not the right thing to do


and david's comment here seems to head in that direction too


My comment is that core.async does not know that js* is a special form, so it takes liberties in rearranging its code when it should not.


A consequence is the defect with and in some cases.


how could it know that and is a conditional ?


if it's a js* it could be anything


I think the core.async bug could be fixed by leaving js* alone and not rearranging code involving it, nor evaluating arguments to js*


so you're basically saying it should be an error to have async code in a form using js*


e.g (* (<! c) 4) is forbidden


I'm saying that core.async has a bug in that it doesn't honor the fact that js* is a special form.


The only consequence of this bug that I'm aware of is evaluation of arguments to js* that shouldn't be evaluated (because they are intended to let JavaScript perform short circuiting via && and ||)


it's not a bug


it's a compromise


core.async evaluates the arguments of js* because if it would not, almost nothing would work as expected


core.async let-binds the arguments to js* instead of just leaving them in the js* form


do you understand what would happen if it would do that ?


All I know is I looked at the way it rewrote the code involving the non-short-circuit bug, and saw that it was moving arguments to *js into let bindings, thus causing them to be evaluated.


that's true, but it does that only because it's the less harmful thing to do in face of a nonsensical special form


I don't really understand what you are saying


ok, let's assume the go macro does what you say : if it encounters a js* form, it just emits it as-is


that means if there's a park in one of the js* args, it's not analyzed


so basically it's forbidden to park in the argument of a js* form


Yeah, if that's the case then there may be certain code that core.async can't compile


yes, as I said even a simple (* (<! c) 4) would be illegal


Yeah, that could be true


I just looked at usages of js* in cljs.core and I'm not even sure which choice would be the less wrong. it's used in so many places, with so many different semantics, moving in either direction would imply a huge rewrite anyways.


actually I find it surprising that core.async even remotely works in clojurescript, when you think about what could possibly happen when js* forms are evaluated


I've also seen issues if you use #js {:foo 1} with core.async, but I've never pinned it down to a simplified defect report


what do you think is the appropriate place to discuss this issue further ?


would it be a recommended thing to define specs in test namespaces (if not using them for anything at runtime)?


@mhuebert I haven't tried this, but it might be possible to guard some stuff with goog/DEBUG to have it DCE'd during :advanced (That way you could leave things roughly where they are, but just guard them.)


I'm curious if (if goog/DEBUG (s/def ::foo int?)) is sufficient, or if that still leaves anything in the spec registry


Seems like a gross solution if it does work, and the compiler would ideally just take care of it for you.


Thanks.. I think for the time being I will just keep them in the test ns, as I haven’t written the specs yet so it isn’t any extra work


avoid the awkwardness and hope involved in DCE


Anybody know how to deal with :npm-deps producing duplicate dependencies? I have two node modules that depend on the same package and it's resulting in two goog.provide for the same package which in turn throws an err


@bill_rubin Might be worth taking a look at to see if it is the same issue


I just looked at usages of js* in cljs.core and I'm not even sure which choice would be the less wrong. it's used in so many places, with so many different semantics, moving in either direction would imply a huge rewrite anyways.


actually I find it surprising that core.async even remotely works in clojurescript, when you think about what could possibly happen when js* forms are evaluated


@mfikes Thanks, seems like the patch works


Cool @bill_rubin if you can, add a comment in that JIRA and also perhaps vote for it.


@mfikes ok will do if I don't discover any new issue


Hey everyone! Has anyone written an Electron app in clojurescript? What was the experience like?

❤️ 4

Not too bad to be honest, I’d recommend making sure that calls into electron are kept in their own namespace, I know that was really helpful when I was trying to fix bugs in the functions for manipulating how I accessed or worked with it. I think I used, as a starting point:

I would also recommend looking up binaryage on github if you don’t know him already, he’s got some nice tools =)… Good luck!


I am building a server-side application with some CSS and JavaScript sprinkled on top (not an SPA). I am wondering if there's a way to have my ClojureScript in the same file as my server Clojure file. I am doing that successfully with CSS using as you can see :stylesheet cash-money.core/screen I am pointing to the exact function path. Is there something like this with ClojureScript where a function gets compiled into a separate file? What are my options?


does anyone here have any experience registering a client to receive events from a server?


i'm not really sure how that works


like, I've seen some js libraries where you call some function that returns an observable object that you can register a callback on, but I don't really know what exactly the server is doing to make that happen