This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-07
Channels
- # bangalore-clj (2)
- # beginners (53)
- # boot (30)
- # cider (27)
- # clara (1)
- # cljs-dev (18)
- # cljsrn (16)
- # clojure (153)
- # clojure-brasil (1)
- # clojure-dusseldorf (5)
- # clojure-italy (20)
- # clojure-losangeles (3)
- # clojure-spec (4)
- # clojure-uk (177)
- # clojurescript (115)
- # component (4)
- # core-logic (1)
- # datomic (29)
- # emacs (9)
- # figwheel (2)
- # gorilla (1)
- # graphql (36)
- # hoplon (4)
- # jobs (1)
- # jobs-discuss (3)
- # juxt (2)
- # keechma (22)
- # lumo (4)
- # off-topic (1)
- # onyx (17)
- # parinfer (96)
- # protorepl (10)
- # re-frame (31)
- # reagent (14)
- # ring-swagger (17)
- # spacemacs (32)
What's the fastest way to encode to JSON from cljs?
My data contains keywords for keys and I need the ability to customize the output some reader tags because some of the data includes compiled js/Function instances (reader tag #object)
@alex-dixon If you want flexibility and can arrange an efficient way to create a seq of keyvals, applying js-obj
to that seq should be pretty fast. It ends up calling goog.object/create
which has a tight JavaScript loop that looks like this, prior to :advanced
for (var i = 0; i < argLength; i += 2) {
rv[arguments[i]] = arguments[i + 1];
}
If your question has to do with encoding to a string,
(.stringify js/JSON #js {:a 1})
seems like it would be pretty fast.Thank you. I think I do want a string…use case is sending large amounts of arbitrary CLJS over the wire. I was looking into CLJS print functions as I thought this might be more performant if I could specify a a custom writer for #object. The functions may be nested so walking to find them seems like a bad way to go. Was hoping I could come across them in the stream and supply a map representation, or at least something that doesn’t blow up the receiving end. Currently sending as EDN to a Clojure server which can’t read #object. Thinking JSON might be best for the rest of the world to consume and potentially faster anyway.
Was support for modules with optimizations :none included in the 1.9.854 release? Loading modules with cljs.loader/load is failing with
Error Cannot write ... after document load at goog.writeScriptTag_
when attempting to load a module. The error does not occur with optimizations :advanced.@dnolen Thanks, I have narrowed it down to a require on cljsjs.react in the module that is being loaded, creating a minimal case at the moment
@dnolen np, minimal case is now available here: https://github.com/symfrog/cljs-modules-react , running
./scripts/brepl
should bring it up on http://localhost:9000@dnolen thanks, I have also added a branch called 'advanced-foreign-order' that attempts to use react-with-addons and results in React DOM being prepended to moduleb.js before React. It can be compiled using
./scripts/release
@symfrog please make a separate repo for that instead of using branches and I will it fork it for tracking
@dnolen the react-with-addons minimal case is now available as a separate repo here: https://github.com/symfrog/cljs-modules-react-order
i.e. it should be possible to reproduce with :foreign-libs
, React doesn’t seem essential to this issue
but I’ll take a look at these - and open issues w/ minimal cases for you if I can repro
i have a semantics question for the new global-exports
: in es6 environments the spec is
import MyThing from 'my-thing'
but in an es5 environment the same require statement would usually be this:
var MyThing = require('my-thing').default
I’m not sure if the second case is actually a verified spec, but in either case how would one configure a global-exports
such that consumers could use my-thing/default
?an example cljs.edn file might be:
:provides ["my-thing"]
:requires ["some-dep']
:global-exports {my-thing MyThing}
But when I do something like this an try to refer to my-thing/default
the default is always nil, and instead I have to (.-default my-thing)
.Hi all! I'm totally new to clojure/clojurescript (But i read a bunch about it)
And now i tried to make a basic project setup with clojurescript which i can connect with cider in emacs.
What i don't understand is that different tutorials use different configurations -
One specifies a seperate figwheel.clj
file for the configuration options, and another specifies the same options under the :cljsbuild
key in project.clj
. And yet another specifies both!
So i wonder what which of them stands for?
@lwhorton there might be another problem here
What version of CLJS are you using?
This is in master but not yet released: https://github.com/clojure/clojurescript/commit/aff39caac5f512fdeda7ad41cdd6224d2d4ca48f
TLDR is if you set :language-in :es6
that'll probably work after that commit
Let me know if it doesn't
i'm getting this warning in my figwheel project:
Cannot infer target type in expression (. cljs.core/PersistentVector -EMPTY-NODE)
thanks @anmonteiro i’ll check this and get back to you
I am trying to interface directly with Preact, a bit like what @thheller has done here (https://github.com/thheller/shadow/blob/master/src/main/shadow/react/component.cljs#L368-L405) but simpler… essentially I want to create a component:
create Test extends Component { render() { return …; } }
to render
my understanding is that I have to create a function, and then use goog.object/extend
on it
is there any simple example code of that? not something that tries to wrap in a framework?
for now, I have something like:
(defn Test [props state]
(cljs.core/this-as this (js/preact.Component.call this props state) this))
(goog.object/extend
(.. Test -prototype) js/preact.Component.prototype
#js {:render (fn [] "…")})
which is probably very wrong because I don't understand it wellHas anyone seen something like this before?
WARNING: No such namespace: goog.math, could not locate goog/math.cljs, goog/math.cljc, or JavaScript source providing "" at line 54
(<-- current version of ClojureScript)
WARNING: No such namespace: goog.math, could not locate goog/math.cljs, goog/math.cljc, or Closure namespace "" at line 54
(<-- previous version of ClojureScript)
Closure namespace ""
<-- somehow it has no idea anymore how to look up a Closure module/namespace?
@plexus The message was updated: https://github.com/clojure/clojurescript/commit/aca54adb69d2ba7c50ac2cd1bea8f1f33555b1e1
I would expect it to say "could not locate JavaScript source providing "goog.math"", but instead it looks for an empty string...
Well, don't know about that, but the problem doesn't seem to be caused by the new version
I think the message is technically correct
but it’s definitely not friendly
I'm just curious what could be causing ClojureScript to think that (require 'goog.math)
could be found in ""... there seems to be something pretty broken with this setup and I have no idea where to start, but this is at least one symptom
Does this problem happen when calling require from REPL or when requiring from another ns?
(ns ... (:require [goog.math :as math]))
works
(require 'goog.math)
doesn't
I'm not sure if require
is supposed to even work like this, isn't that for REPL use?
@plexus sorry I’m confused now
are you having trouble requiring goog.math
?
actually, no. It seems to be fixed now. I think it was actually being used without being required. Sorry for the noise.
@plexus OK so the error was expected 🙂
I've been banging my head against this build setup for most of the day and this was one symptom that seemed like it could help to explain things, but it was a red herring
the ""
refers to JS modules though
that’s why I said the error message is technically correct
yes, not friendly at all
I’ll look into it
^ this fixes it
I am looking to loop over an array of html elements in clojurescript and add event listeners to each element in the array. What would be the best practice for this in cljs? a doseq
?
if you don’t need return values, yeah, use doseq
or run!
, if you do need any return value use reduce
Cheers, noisesmith!
is there anything that give two datetimes (like now and a specific date), that would return me the difference in - years, months, days, hours?
I can probably implement it myself otherwise, but seems like something might be useful to many people
I'm just trying to implement a simple countdown
@andrea.crotti @noisesmith Joda-time obviously has this built-in but this being Cljs channel this is probably about JS. Goog.date doesn't have this built-in: https://google.github.io/closure-library/api/goog.date.html
@andrea.crotti This is my time-ago component, maybe it is of some help: https://github.com/metosin/komponentit/blob/master/src/cljs/komponentit/timeago.cljs#L10, pretty much it just takes difference of timestamps and divides that
cljs-time and interval gets me close to what I need
ah yes that's cool I can still some of that for the rest
cljs-time unparse-duration
might do this: https://github.com/andrewmcveigh/cljs-time/blob/d1ad057e832aebf14b6cd08429aa54d9cdb1ea11/src/cljs_time/format.cljs#L279
The goog.date.duration
namespace looks nice, and it has a format
fn:
cljs.user=> (duration/format 1000000000)
"11 days 13 hours 46 minutes"
That's the one unparse-duration
calls
And now that I'm looking at goog.date.duration
code, I remember it is also what I used before writing that time-ago
code, but the formatting wasn't really customizable there
mm yeah that one is good
but annoyingly it does all the logic in the format
so can't really reuse it
ah wait no sorry cljs-time does it
didn't read correctly
ah no it doesn't take it back
ok well I have to see if it's more annoying to parse that to the values or to implement it myself
I've found this library to provide the best flexibility: https://github.com/EvanHahn/HumanizeDuration.js
ah that's pretty good thanks @ayidi
I do enjoy watching the js-closure compiler run over all my node_modules dependencies on compilation thanks to 1.9.854
. lots of warnings in some of the libs makes me reconsider my actual dependency on such libs. regardless — i’m actually getting a larger bundle size (1.3mb vs 1.4mb)
after using the global-exports from node_modules and closure advanced compilation. What might cause this?
@lwhorton :global-exports
is opposite of node_modules
If you use node modules, (:require [react :as react])
requires the React code which Closure has converted from CommonJS module to Closure module
:global-exports
is a way for foreign-libs (e.g. browserified JS from Cljsjs) to emulate names that npm packages provide, to ease the transition
So if you have the packages installed to node_modules
, you aren't using :global-exports
As for the size, hard to say, on my testing using only React was a bit smaller (5%) and it would make sense that advanced optimization and dead code elimination will make the output smaller, but converting JS code from CommonJS to Closure is quite complicated so it is very possible there are cases where it doesn't work very well
how does that tie in to cljsjs? surely the compiler has to read an externs file from somewhere? I see a few more-recent cljsjs packages define two entries in their :foreign-libs
where one exports a cljsjs package, and the other entry uses global exports (here for example https://github.com/cljsjs/packages/blob/master/react/resources/react-deps.cljs )
With node modules, using Closure module processing, externs are not always necessary. As both app and library code go through Closure processing, the names are mangled in both cases.
But many libraries (e.g. React) create objects in some dynamic way that Closure can't understand, so externs are still required for those cases (https://github.com/facebook/react/issues/9417)
It is possible to use Cljsjs packages to provide externs even when using node modules, because Cljs compiler will use node modules over foreign-libs.
If you have React installed at node_modules, cljsjs/react JS code doesn't get used
Yes, all the externs from all the deps.cljs files are always loaded
I see. thanks again for the clarification. Makes sense that there’s a lot of code required to closure-ize non-conformist libs
If I want to work on a #object[NodeList [object NodeList]]
, which, to my understanding, has a limited set of core clojure methods that can be applied to it, is creating a protocol the only way to do this? As outlined in this article: http://blog.altometrics.com/index.php/2016/05/02/protocols-in-clojurescript/
My goal is to run a doseq
against the result of (def el-keys (.querySelectorAll js/document ".key"))
- the result is #object[NodeList [object NodeList]]
.
right now If I run (doseq [el-key el-keys] (p el-key))
I will get the following error in the console: Uncaught Error: [object NodeList] is not ISeqable
you'll need to find out what the real api is for getting the next item sequentially, then wrap that in a function that makes an ISeq instance
probably the easiest way is to use iterate
and take-while
if it has the typical sort of getNextItem method
or actually repeatedly
could be the key - something like (take-while identity (repeatedly #(.nextElement source)))
depending on what the method is and how that method api works