This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-06-19
Channels
- # aws-lambda (1)
- # beginners (35)
- # cider (7)
- # cljsjs (2)
- # clojure (48)
- # clojure-austria (1)
- # clojure-conj (9)
- # clojure-dev (8)
- # clojure-india (6)
- # clojure-italy (12)
- # clojure-nl (8)
- # clojure-norway (3)
- # clojure-spec (9)
- # clojure-uk (92)
- # clojurescript (103)
- # community-development (7)
- # cursive (15)
- # datomic (75)
- # devcards (3)
- # emacs (3)
- # events (1)
- # fulcro (129)
- # hoplon (4)
- # immutant (2)
- # jobs (10)
- # leiningen (9)
- # off-topic (4)
- # onyx (2)
- # re-frame (45)
- # reagent (39)
- # reitit (40)
- # remote-jobs (4)
- # ring (2)
- # ring-swagger (9)
- # shadow-cljs (17)
- # tools-deps (31)
@wilkerlucio in what environment are you testing, and or are you using any testing libraries?
@bhauman now that you mentioned, I did included fulcro-spec, but wasn't using on the given example, but seems like it's leaking there, found it on fulcro-spec code
thanks for bringing the question đ
I got the new webpack support working ok following the guide (https://clojurescript.org/guides/webpack) but have not been able to get it to work in conjunction with lein-cljsbuild, anyone else tried this yet?
@wilkerlucio unrelated note, maybe consider using the latest cljs-devtools, to get rid of that âMapEntryâ types: https://github.com/binaryage/cljs-devtools/releases/tag/v0.9.10
@darwin thanks! one idea, had you though about giving some option to sort the map keys in the output?
đ Been working on JS to ClojureScript transpiler. Should be useful for beginners to play with small code samples and see how it looks like in Clojure. Obviously itâs not gonna generate very idiomatic Clojure, but it tries to do so đ https://roman01la.github.io/javascript-to-clojurescript/

I'm in the process of moving to :npm-deps
for our project at work. However, I'm running into an issue where one of the npm-deps is written using ES6 and using export default ...
. The optimization pass (right now simple
) throws various errors like JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT6 mode or better: modules
. My first guess was setting :language-in
and/or :language-out
in the compiler options, but every combinations trigger other errors.es6 as in, es5 as our for example triggers the error that modules can only use either export default
OR goog.provide
, but the files in out/node_modules/<dep-name>/dep.js
contain a goog.provide
with a custom Clojurescript package path module$home$moritz$...
at the top and the es6 export
at the bottom.
The dependency in question also includes non-es6 compatible code in a different subdirectory. The package.json
specifies both: "main": "lib/index", "module": "es/index"
. es/
contains the es6 stuff, lib
contains the "normal" stuff.
@the-kenny unless youâre willing to sink a lot of time to sort out these kinds of issues I would probably not go this route - whatâs stopping you from just going the Webpack double bundle (now officially documented) route if you need to consume node_modules
?
@dnolen We wanted to try the npm-deps stuff. Just ran into this issue half an hour ago or so. If there's no simple fix we'll go back to the separate webpack bundle approach. Our major goal was simplifying the use of external libraries, especially related to externs. Right now we have a bundle.js
which includes all javascript libs and re-exports them for clojurescript. This requires manual maintenance of our externs. We can't use cljsjs for most stuff as other non-cljsjs-packaged stuff has dependencies on it. Is your double-bundle something different than this simple bundle.js + app.js approach?
there may be some minor issues around externs - but this is way more tractable to fix quickly then :npm-deps
I'll have a look, thanks đ We really neglected the whole client side compilation story for way too long
:npm-deps
requires too much coordination between practice, ClojureScript, and Google Closure Compiler for now - itâs promising but simply too fiddly
externs inference + global-exports removes nearly all of the major previous annoyances
yeah, that was my impression too. Worked quite fine for most stuff, but the es6 stuff seemed like some major issue
and because foreign-libs can be overriden - you can build whatever you want and stuff like Reagent just works anyway
@the-kenny small favor, if you could produce a minimal case and file what you encountered that would be very helpful
just JIRA ticket, just do this in the most minimal way possible - no other tooling etc.
I got burned today by CLJS (I believe somewhat new) map entry introduction.
(into {}
(comp (map (fn [[k v]]
[k (inc v)]))
(filter (comp pos? val))) ;; <- `val` is going to fail, replace with `second` to fix
{:x 1})
I get why it fails, val
can only be called on a map entry. It makes writing transducers awkward
It used to not fail in fairly recent cljs versions. Iâd have to track all that down to see why, just thought Iâd post on the general concept.
[org.clojure/clojurescript "1.10.312"]
then again, this is the same in CLJ, so Iâm sure it is going to be written off as âintended behaviorâ. I guess a map-entry constructor would be nice, but thatâs still extra stuff to miss
I think maybe a takeaway is that I should really reserve key
and val
usage to perhaps when perf needs.
it doesnât seem to be good in transducers because it canât compose with functions like above where the âmap entryâ may be devolved to a 2-vector
For anyone who is interested in following along:
[it seems to surprisingly work but i could see how some may have stylistic concerns about it]
@mikerod have you considered using specter for that transformation? potentially more concise and probably sidesteps the issue you ran into
@johanatan it was just a contrived example
still in whatever use case you may have wanted to avoid that situation for in the wild, specter could be a solution
Iâm aware of specter though and know how it can possibly help in nested transformation cases etc
I donât know that Iâd think to use spector for a small composed transducer though
@johanatan sorry was completely confused
cljs.user=> (require '[goog.object :as gobj])
nil
cljs.user=> (gobj/get js/process.env "blah")
nil
cljs.user=> (defn getenv [v] (gobj/get js/process.env v))
#'cljs.user/getenv
cljs.user=> (import '[goog.string format])
nil
cljs.user=> (format "blah: %s" nil)
"blah: null"
cljs.user=> (format "blah: %s" (getenv "blah"))
[goog.string.format] Not enough arguments
replacerDemuxer (evalmachine.<anonymous>:78:13)
String.replace (NO_SOURCE_FILE <anonymous>)
Object.goog.string.format (evalmachine.<anonymous>:87:19)
(evalmachine.<anonymous>:1:13)
ContextifyScript.Script.runInThisContext (vm.cljs:50:33)
Object.runInThisContext (vm.cljs:152:38)
(Object._t)
(Object.lumo.repl.caching_node_eval)
(NO_SOURCE_FILE <embedded>:6127:273)
E (NO_SOURCE_FILE <embedded>:6128:269)
cljs.user=> (getenv "blah")
nil
anyone know what is going on with the above ^^ ?further reduced:
cljs.user=> (format "blah: %s" (gobj/get js/process.env "blah"))
[goog.string.format] Not enough arguments
replacerDemuxer (evalmachine.<anonymous>:78:13)
String.replace (NO_SOURCE_FILE <anonymous>)
Object.goog.string.format (evalmachine.<anonymous>:87:19)
(evalmachine.<anonymous>:1:13)
ContextifyScript.Script.runInThisContext (vm.cljs:50:33)
Object.runInThisContext (vm.cljs:152:38)
(Object._t)
(Object.lumo.repl.caching_node_eval)
(NO_SOURCE_FILE <embedded>:6127:273)
E (NO_SOURCE_FILE <embedded>:6128:269)
this is my workaround for now (which works as expected):
(defn log-value [value-name value]
(js/console.log (format "%s: %s" value-name (when value value))))
@johanatan I can repo in lumo
. Even crazier:
cljs.user=> (defn always-nil [] nil)
#'cljs.user/always-nil
cljs.user=> (format "blah: %s" (always-nil))
"blah: null"
@lee.justin.m how is that "crazier"? seems expected to me
right. itâs crazy that the getenv
function does something different than a function that supposedly evaluates to the exact same thing
but the root of the problem seems to be gobj/get
(whether it is wrapped by another function or not)
@lilactown i tested the value returned from gobj/get
against nil?
and #(= % nil)
and it behaved as expected
cljs.user=> (format "blah: %s" js/undefined)
[goog.string.format] Not enough arguments
replacerDemuxer (evalmachine.<anonymous>:78:13)
String.replace (NO_SOURCE_FILE <anonymous>)
Object.goog.string.format (evalmachine.<anonymous>:87:19)
(evalmachine.<anonymous>:1:13)
ContextifyScript.Script.runInThisContext (vm.cljs:50:33)
Object.runInThisContext (vm.cljs:152:38)
(Object._t)
(Object.lumo.repl.caching_node_eval)
(NO_SOURCE_FILE <embedded>:6127:273)
E (NO_SOURCE_FILE <embedded>:6128:269)
itâs returning undefined which prints out as nil but apparently doesnât work the same way
https://github.com/google/closure-library/blob/master/closure/goog/string/stringformat.js#L79
i think that code would be more robust if it checked for the length of args and just printed out âundefinedâ but at least i undersatnd
yes thatâs what I would do. iâm still a bit mystified at where the type coercion is happening
this seems related: https://groups.google.com/forum/#!topic/clojure/f0q9kHwMQ7Q
this is what i mean by âcoercionâ:
cljs.user=> (nil? js/undefined)
true
cljs.user=> (identical? nil js/undefined)
false
which expands to
(core/defmacro coercive-= [x y]
(bool-expr (core/list 'js* "(~{} == ~{})" x y)))
@lee.justin.m ah, yea. that's a bit surprising