Fork me on GitHub
#clojurescript
<
2016-11-25
>
aengelberg03:11:14

I'm trying to run lein-cljsbuild on my project, but I'm encountering an error during the macro (clj) compilation step which implies that namespaces are getting reloaded in the wrong order. On the classpath I have files instaparse/core.cljc depends on instaparse/gll.clj depends on instaparse/auto_flatten_seq.cljc. In all three of those files, I put debugging println's like so:

(println "begin my.ns")
(ns my.ns
  ...)
(println "loading my.ns")
and the output looks like:
Compiling ClojureScript...
begin instaparse.gll
begin instaparse.auto-flatten-seq
loading instaparse.auto-flatten-seq
loading instaparse.gll
begin instaparse.gll
loading instaparse.gll
begin instaparse.auto-flatten-seq
loading instaparse.auto-flatten-seq
begin instaparse.core
loading instaparse.core
Reloading Clojure file "/instaparse/core.cljc" failed.
clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: instaparse.auto_flatten_seq.AutoFlattenSeq cannot be cast to instaparse.auto_flatten_seq.AutoFlattenSeq, compiling:(core.cljc:284:14)

aengelberg03:11:26

Am I correct that this is bad behavior?

aengelberg03:11:27

The reason this error is occurring is because auto-flatten-seq is getting reloaded without gll getting reloaded afterwards. I can reproduce that same error by executing cider-load-buffer in my editor, in that bad order.

aengelberg03:11:41

In comparison, running lein test (i.e. using the regular clojure compiler) results in:

begin instaparse.core
begin instaparse.gll
begin instaparse.auto-flatten-seq
loading instaparse.auto-flatten-seq
loading instaparse.gll
loading instaparse.core
which I would expect.

martinklepsch10:11:31

how can I refer to a global like js/Stripe that does not break when the global is not defined? I want to pass it to something that will eventually run (exists? js/Stripe)

martinklepsch10:11:21

@mccraigmccraig I see, thanks. Had hoped for something in the stdlib but well...

mccraigmccraig10:11:53

maybe there is something - i couldn't find it at the time

martinklepsch10:11:55

couldn't find something either haha

martinklepsch10:11:25

I now went with a different API that takes a fn like #(exists? js/Stripe) instead of just the global

martinklepsch10:11:23

asked for this post: https://www.martinklepsch.org/posts/just-in-time-script-loading-with-react-and-clojuresript.html — small guide to loading scripts when you need them using higher order components

mitchelkuijpers10:11:11

@borkdude I find the default behavior very weird tbh

thheller10:11:08

@aengelberg why are things getting reloaded while compiling? does your ns have a :reload flag?

thheller10:11:47

@martinklepsch you could also turn js/Stripe into a prop instead of a global. for your example [thing-that-uses-stripe {:stripe js/Stripe}]

thheller10:11:11

the component can now refer to (:stripe props) instead of the global

thheller10:11:37

and check if that is nil? without worrying about where it came from

martinklepsch10:11:49

@thheller is that meant as an improvement or different approach?

martinklepsch10:11:02

I think you usually don't want to pass complex objects as props

thheller10:11:26

well I don't like working with globals 😉

martinklepsch10:11:56

Yeah, I think stylistically it's nice and might be handy for testing but it felt a bit out of scope in this particular post

thheller10:11:42

also you probably want to turn those args into functions

thheller10:11:45

[js-loader {:scripts {#(exists? js/Stripe) ""}
            :loading [:div "Loading..."]
            :loaded [payment-form]}]

thheller10:11:11

:loading and :loaded I mean

thheller10:11:27

otherwise they are both eval'd at the wrong time

thheller10:11:47

also you can probably skip the #(exists? js/Stripe)check and just check whether "" completed loading or not

thheller10:11:29

(def things-that-finished-loading (atom #{})) and just conj into that on-load

martinklepsch10:11:03

@thheller but then I end up with state vs. a simple fn? 🙂

martinklepsch10:11:04

@thheller I'm not sure I'm following about the "eval'd at the wrong time" they are only turned into components if they're actually supplied as part of some :reagent-render fn; no? Until then they should be just vectors?

thheller10:11:34

yes they are only vectors

thheller10:11:49

still they are vectors

thheller10:11:27

ie. :loaded [payment-form {:stripe js/Stripe}]

thheller10:11:30

will not work

thheller10:11:49

as it is created when js/Stripe is still nil

martinklepsch11:11:50

I see what you mean, yeah, didn't take that into account

martinklepsch11:11:16

Stripe will log a warning if you load it twice btw

pesterhazy11:11:44

I get this exception after updating to ClojureScript 1.9.293. Anyone know what this is about?

clojure.lang.Compiler$CompilerException: java.lang.Exception: namespace 'cljs.source-map' not found, compiling:(cljs/compiler.cljc:9:1)
                    java.lang.Exception: namespace 'cljs.source-map' not found

thheller11:11:13

@pesterhazy probably a tooling issue, did you try lein clean first?

danielgrosse12:11:47

Is there videoplayer, which works nicely with clojurescript?

danielgrosse12:11:57

Especially Reagent

mccraigmccraig12:11:37

@danielgrosse youtube and vimeo both have iframe based players which work fine with reagent

danielgrosse12:11:06

I need a self hosted player

mccraigmccraig12:11:16

for what platform/s ?

pesterhazy12:11:50

@thheller, I'm using boot, so there are no temp files to clean up. Any deps I should look at?

martinklepsch12:11:05

@pesterhazy have you checked boot show --pedantic just in case?

pesterhazy12:11:39

works with .89 by the way

pesterhazy12:11:35

@martinklepsch, I get a couple of red Xs, what should I be looking for? clojurescript is not among them

danielgrosse12:11:14

Modern Browser. IE10 and higher

martinklepsch12:11:18

@pesterhazy mostly if clojurescript is among them ;D

martinklepsch12:11:15

@pesterhazy maybe try tenzing with the same versions to see if it's a more general issue with boot-cljs and recent versions of cljs, there's nothing in the issue tracker though so I'd expect things to work

pesterhazy12:11:40

is there a list of stable releases somewhere? https://github.com/clojure/clojurescript/blob/master/changes.md doesn't distinguish stable from unstable

martinklepsch12:11:51

I think releases announced on the mailinglist are considered to be stable

martinklepsch14:11:07

@knaman you could map over the vector with a function that replaces a thing if it matches. Whatever you do you don't get around the fact that you need to traverse the entire vector

martinklepsch14:11:37

@knaman I made this a while ago which sort of goes in that direction as well: https://github.com/martinklepsch/custom-comparator-set

knaman15:11:08

@martinklepsch "a thing" my new map is 99% different from the original one, is there no way to just say use this map in place of the old one

gfredericks18:11:37

there's a JS engine in the JVM, isn't there? Does anybody know if it runs CLJS correctly?

juhoteperi18:11:05

@gfredericks Yes, Rhino (old one) and Nashorn. Rhino can be used for repl and Cljs compiler includes tests for Nashorn, so both should work.

gfredericks18:11:48

Ok cool, thanks

aengelberg20:11:39

@thheller: No, no :reload flags as far as I know, which is why I'm concerned the cljs compiler isn't doing the right thing.

mfikes20:11:48

@aengelberg There is a known issue that libraries listed ClojureScript namespace forms are not processed in the textual order implied by the code, but it looks like you are off in Clojure ordering with the macros.

aengelberg20:11:38

@mfikes: Yeah, it seems like the errors I'm encountering is purely the "Clojure half" of the ClojureScript compiling process.

aengelberg20:11:28

Does cljsbuild do anything weird regarding loading clj/cljc files that's different from the regular Clojure compiler?

gfredericks22:11:59

I've been using cljsbuild & cljc in the test.check codebase for a while haven't noticed anything too weird