Fork me on GitHub
#clojurescript
<
2020-05-07
>
Lyn Headley02:05:32

Anybody have an example of building a cljs app with :optimizations :advanced that avoids externs by using cljs-oops to call a function imported from an es6 module pulled from npm?

ingesol09:05:21

I’m compiling my project with :bundle target and advanced optimisations. I’m getting an error from sente usage, where the statement

(.setTimeout goog/global connect-fn backoff-ms)
is compiled so that goog/global becomes aa and fails on no setTimeout . Is this something that’s supposed to “just work” with externs inference?

Jakub Holý (HolyJak)10:05:05

Out of curiosity, what is goog/global ? I have never seen it before. If it is something from the Closure library then the closure compiler should understand and not mess it up and rename all its occurences ok? Or did you perhaps mean js/myGlobalVar ?

ingesol10:05:17

Only thing goog-related in my inferred externs is goog.DEBUG

Jakub Holý (HolyJak)12:05:03

OK, found it here https://google.github.io/closure-library/api/goog.html#global This is something from the Closure lib so it is really weird that the compilation screws it up. Your only hope is @dnolen , @U04VDQDDY or one of the other allmighty clojurescripters. I guess it is OK that the compiler renames goog/global to aa but the fact that it then fails to call setTimeout on it shows that the renaming has not happened everywhere. How is that possible, for a Closure library's own var, I have no idea.

ingesol13:05:02

You were right about this requiring experts 🙂

Jakub Holý (HolyJak)10:05:18

Hello! Any idea if there is a way in transit-js to get it output bigdecimals in a nicer way than [TaggedValue: f,123.45] when I (str bigdec) it? The stringification is defined here https://github.com/cognitect/transit-js/blob/master/src/com/cognitect/transit/types.js#L43 I do not see a way to do that... 😞 Perhaps I could try to replace types.TaggedValue.prototype.toString with something smarter...

dnolen13:05:40

@ingesol that's not covered by externs inference

dnolen13:05:14

and I'm not really sure that is supposed to work? since the type of goog.global can't be known by Closure Compiler it perhaps can't infer that it is in fact Window or something else

dnolen13:05:26

js/setTimeout is preferred I would say. The global require stuff I'm thinking about for the next release would clean this up a bit - but effectively result in the same thing but without having to explicitly handle goog/global references in your file.

thheller13:05:37

@dnolen didn't you add a define to address this. so that it sets goog.global = window or something?

dnolen13:05:14

er sorry yes

dnolen13:05:31

it defaults to window I think, and you can control that

dnolen13:05:08

(actually sorry it might not default)

thheller13:05:14

it is not the default and don't make it please 😛

dnolen13:05:28

@thheller I'm pretty sure there is no default

dnolen13:05:22

yes no default

dnolen13:05:30

you must set it explicitly to get anything

ingesol13:05:40

@dnolen ok. This code is inside https://github.com/ptaoussanis/sente. I tried to add an extern, but no go, I’m probably not doing it right. My attempts were

goog.prototype.global {}
and
var goog {
  global: function() {}
}

dnolen13:05:42

so that was intentional

dnolen13:05:58

@ingesol Object.setTimeout;

thheller13:05:51

no... this has nothing to do with externs. goog.global just isn't what you think it is and doesn't have setTimeout. @ingesol you need to configure the closure-define so that it uses window.

ingesol13:05:09

ah, ok. My inferred externs already contain Window.prototype.setTimeout; and `

var setTimeout;

thheller13:05:28

:closure-defines {'cljs.core/*global* "window"} I think

dnolen13:05:01

right, but I like said above, this level of config over js/setTimeout doesn't seem that meaningful

thheller13:05:44

actually the closure library itself uses goog.global.setTimeout instead of setTimeout IIRC

dnolen13:05:08

ah true, if the problem here is that goog.global is just wrong period, then @thheller suggestion is best

dnolen13:05:15

and I guess it is

thheller13:05:35

normally goog.global = this will use window as the this when the script is loaded but after webpack is done with it it won't be. so need to make sure to set it to window manually.

dnolen13:05:17

sorry, lost the thread, forgot we were talking about :bundle

dnolen13:05:14

forgot about this subtlely adding it to the webpack guide

ingesol13:05:42

@dnolen @thheller Thanks, the closure-defines snippet seems to have moved me one step forward on this journey towards a successful advanced bundle build

👍 4
Jakub Holý (HolyJak)16:05:30

When done, consider please updating the relevant guide(s) / pages for us others!

dnolen16:05:42

already done

❤️ 4
Adrian Smith14:05:44

I wonder if the new bundling stuff means you could progressively introduce cljs into a typescript app

Bit Sadhu14:05:45

Dear community, greetings to all of you. I started my Clojure endeavour a while ago, mostly I was reading books, but recently first time I had an opportunity to actually try Clojurescript on the simple single page app. So far so good. Didn't thought I will need help but turns out I do. I am not going to lie my brain is getting slightly damaged, and this is what puzzles me: Goal is simple, - use WebSockets to send commands to the end-point (written in Python, I have no control of it) and get responses back. Nothing fancy. Basic code snippet:

(def socket (js/WebSocket. ""))
(def data {:command "cmd" :sequence_number 1})
(defn clj->json [ds] (.stringify js/JSON (clj->js ds)))
(.send socket (clj->json data))
In REPL works as expected, sending JSON over the WebSocket. Great. Python (end-point) can read JSON and produce dictionary. BUT In Browsers Chrome/Safari produces
#error {:message "Invalid keyword: .", :data {:type :reader-exception, :ex-kind :reader-error}} edn.cljs:420
If I do
(.send socket (pr-str (clj->json data)))
it works but end-point not able to parse JSON into Dictionary "json.load" (python function) produces the string, it is not acceptable. I am doing something very stupid probably and solution is very obvious. Could you please point to the right direction? It is really a blocking issue to me. FYI: My desire is not to install any other libraries for WebSockets and keep it simple and minimal.

dnolen14:05:18

@sfyire wasn't intended for that but I don't see why not. there might be some missing bits to make that work a little better - i.e. referencing local JS files - I believe we really only look at node_modules - not super high priority since it's still my impression this is much smaller use case demographic

dnolen14:05:34

@bitsadhu I think you're ignoring the invalid keyword thing - something is wrong with the EDN payload - it should be pretty obvious if you look at it

Bit Sadhu14:05:38

@dnolen Thank you, I will check it.