This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-26
Channels
- # 100-days-of-code (3)
- # announcements (2)
- # beginners (237)
- # bitcoin (2)
- # boot (5)
- # cider (15)
- # cljs-dev (9)
- # cljsrn (6)
- # clojure (75)
- # clojure-estonia (1)
- # clojure-italy (8)
- # clojure-losangeles (1)
- # clojure-nl (1)
- # clojure-spec (68)
- # clojure-uk (80)
- # clojurescript (89)
- # cursive (31)
- # datomic (22)
- # emacs (2)
- # events (3)
- # figwheel-main (184)
- # fulcro (28)
- # graphql (1)
- # hyperfiddle (2)
- # jobs (1)
- # jobs-discuss (64)
- # luminus (5)
- # off-topic (16)
- # om (2)
- # onyx (1)
- # pedestal (12)
- # portkey (1)
- # re-frame (13)
- # reagent (56)
- # reitit (13)
- # ring-swagger (13)
- # shadow-cljs (145)
- # slack-help (2)
- # specter (6)
Hi folks, ran into a problem last night and trying to clarify my understanding of the cljs compilation process. I'm bundling a js library via webpack and pulling it in as foreign-libs in an attempt to bypass advanced compilation. The Clojurescript docs clearly state that "foreign libraries are included in your final output, but are not passed through advanced compilation." My hope was that by avoiding advanced compilation on the js lib, I would not have to deal with externs, and get a more reliable build in advanced compilation mode. However, even as foreign libs, the names in the js lib still get renamed, and nothing seems to work unless I add the :infer-externs
compiler options to true
. Even with :infer-externs
set, I've come across the "<some-method> is not a function" error, which I was only able to resolve by using string names for the methods. It appears everything is still being renamed in the js foreign lib as part of the compilation process, which is confusing because I thought that renaming is part of advanced compilation mode, and foreign libs were supposed to bypass that. Any thoughts that might help clarify things?
@zalky afaik the thing is that your code goes through advanced compilation even though foreign lib doesn’t. Any references you make to foreign lib in your code gets munged and that’s why it breaks if you don’t have externs to tell closure compiler “please don’t munge these”. :infer-externs
is a nice tool to do the externs part for you but it’s not perfect and sometimes you need to provide type hints to make it work. You can add (set! *warn-on-infer* true)
in the beginning of your namespace to get compile warnings when externs inference fails and get notified when type hints are needed
Gotcha, I think I see now that it's the munging on the cljs side that is the problem, and unavoidable with advanced compilations.
however you may write some interop with a foreign lib and there’s a few cases where you must hint the compiler
I’ve been working with non-trivial foreign libs on a client project and I’ve encountered no issues with :infer-externs
so far myself
@dnolen, success! Thanks for the pointer that's really helpful. However, I notice you do not appear to need the type hint with every (fn [x] (.foreignMethod x))
. So is this context dependent on the particulars of x
?
@zalky nah its just the name itself. if its found in any externs at all it won't be renamed so its just accidental they don't get renamed. it is safer to always typehint values so you don't run into issues when the other externs get removed/changed for some reason
we have a case where very occasionally (as in, maybe 1 in a few hundred) the generated javascript is different… and the different case actually causes a runtime error.
@lwhorton you should probably ask first in #cljs-dev then in case report it to Jira
@lwhorton important to make a minimal reproducer for something like that, but yes take it to #cljs-dev
yea i just listened to your talk about simpler tools and tools deps for producing minimal cases 🙂 ill attempt it later today
Is there a similar feature with Clojurescript projects, eg that you could specify js-source-path
and have them compiled with your clojurescript?
I know you can have js-files around in figwheel.main, but they need to do the goog.provide()
thing.
you can import ES6 stuff, but different syntax for Closure stuff? Also can’t import ClojureScript stuff?
That’s a shame, I almost have this problem now. We have a huge js-SPA at work which we want to “reassemble”. It’s written with all kinds of modules, ES-6 and require.js at least.
A bit late reply, but have you looked at shadow-cljs? I think it should give better interop support with JS https://shadow-cljs.github.io/docs/UsersGuide.html#_language_support
pretty much the only reason transit-js would have been in ES6 would be to get JS people to contribute
So my use case would be to write the core in cljs and “port” existing parts/views from the old app over to the cljs-app without having to rewrite everything into cljs.
Hey guys! Do you have any recommendation on how to get JSON from a REST API endpoint (url) to a ClosureScript vector? (I'm guessing, as I want to display the data by looping it with OM. Currently I've tried to get JSON data with ajax.core (GET "url"), which returns the data, but as a text string not as JSON
(-> my-string js/JSON.parse js->clj)
or use fetch, like so: https://github.com/pesterhazy/cljs-spa-example/blob/master/src/cljs_spa/page/users.cljs#L5
I believe you can just do :format :json
— the library is a little confusing because it has a “simple” style and a “complex” style. you just need to read the docs and pass the magic words to it depending on how you are invoking it
it is possible to customize the response handler too, which I did so that it doesn’t keywordize numeric keys
but really, (-> (js/fetch url) (.then #(.json %)) (.then js->clj) (.then (fn [r] (do-something-with r)))
is usually easier, no library needed
It's my second day with Closure (new job, must master it) and so what I'm trying to do is instead of hardcoding (defonce app-state (atom {:data[{.... , I would get all that with a call.
I'll try it out
is there a better way of creating fully qualified keywords from unqualified keywords than this? (map #(keyword (namespace ::x) (name %)) (keys {:a 1 :b 2}))
when using transit what is the best way to keep 1.0 as a float and not have it turn into 1? Is a custom tagged value the only real way forward?
Hey, I know this gets asked every now and then, but I can't really find the answer. What is a good client side router for cljs? Secretary's current build is apparently failing and hasn't been updated in 2 years
@idiomancy I've been enjoying https://github.com/metosin/reitit