This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-22
Channels
- # beginners (240)
- # boot (23)
- # bristol-clojurians (3)
- # cider (101)
- # cljs-dev (52)
- # cljsrn (17)
- # clojure (212)
- # clojure-dusseldorf (2)
- # clojure-greece (2)
- # clojure-italy (9)
- # clojure-russia (1)
- # clojure-spec (91)
- # clojure-uk (33)
- # clojurescript (164)
- # community-development (23)
- # core-async (24)
- # core-logic (9)
- # cursive (18)
- # datavis (1)
- # datomic (119)
- # emacs (13)
- # events (1)
- # figwheel (2)
- # fulcro (86)
- # graphql (1)
- # immutant (5)
- # jobs-discuss (6)
- # leiningen (19)
- # lumo (46)
- # nyc (7)
- # off-topic (23)
- # parinfer (15)
- # pedestal (3)
- # planck (32)
- # re-frame (48)
- # reagent (75)
- # ring-swagger (13)
- # rum (32)
- # shadow-cljs (402)
- # spacemacs (5)
- # specter (3)
- # tools-deps (11)
- # unrepl (20)
- # vim (135)
- # yada (3)
hi all, i've been struggling with writing regex that validates if the input is a linkedin url. writing a really simple regex expression into the cljs repl works, eg
(def r #"http")
however, this doesn't seem to work, eg (def r #"https:\/\/www\.linkedin\.com\/in\/.*")
this is the error i get:
#object[SyntaxError SyntaxError: Invalid regular expression flags]
figwheel$client$utils$eval_helper (jar:file:/Users/evangeline/.m2/repository/figwheel/figwheel/0.5.3-2/figwheel-0.5.3-2
the weird thing is everything works for me in a clj repl/clj file, but breaks when it's in cljs repl/cljs file. any advice would be awesome 🙂
@evangelinechengg You don't need to escape /
in regex created with the reader #
got it, thanks!
I'd like to try out the aot-cache in a project that uses lein for the build config. The cljsbuild compiler options are
{:main cljs.user,
:preloads [devtools.preload],
:asset-path "/js/compiled/out",
:output-to "resources/public/js/compiled/app.js",
:output-dir "resources/public/js/compiled/out",
:source-map-timestamp true,
:aot-cache true,
:closure-defines {re_frame.trace.trace_enabled_QMARK_ true}}
When starting up figwheel (0.5.15) repl I get the error message
Found unrecognized key :aot-cache at path (:cljsbuild :builds 0 :compiler)
Must be one of: ...
Do I have to use a non-stable figwheel release?A :validate-config false
in the figwheel configuration resolved the problem. It now builds, but other issues are happening. Because of time running out I'll go back to :aot-cache false
for now.
Is anyone using integrant with cljs?
https://github.com/weavejester/integrant
It seems that load-namespaces
is only available in the clojure implementation… which appears to be because require
is unavailable in clojurescript. Is that right?
I’ve seen that lumo
however does let you do require
; but it appears that lumo implements require
as a macro, which obviously means that it behaves very differently to in clojure where it’s a function.
My motivation is that I’d like to use integrant to componentise things (so they’re not in the ns require tree), but are in a configuration file… but it seems this is going to be awkward. Also I’m not entirely sure on the point of integrant working with cljs if it can’t load-namespaces.
I suspect this is because of clojurescript using the clojure compiler…
i.e. I’d have to require every namespace in the app to load it… which is duplication.
I guess I’d have to make load-namespaces a macro to work with lumo… macro contagion.
@rickmoynihan Clojure tools that rely on reified vars and namespaces are unsuitable for ClojureScript
@dnolen: Yeah, I think this is what I’m finding 🙂
@rickmoynihan there are some very restricted things that aren’t challenging, cljs.test
is a good example
I had to explicitly bump the tools.reader version, but I don’t know if it’s related to cljs.
yeah i understand
or at least I understand why it might be necessary to resort to hacks like this… as in cljs the read/compile/eval cycle is split across languages, so I can see why require actually needs to trigger compilation (by triggering the reader) and therefore needs to be macro so it happens at the right time. i.e. implication of having two different environments. Is that more or less right?
sure — but require triggers load which triggers the eval cycle right? In clojure anyway?
yeah which is what I’m finding. And that’s why it has to be a macro… i.e. to force contagion
and force that it happens at compile time when clj env is available?
@rickmoynihan that’s not true
ahh ok. Interesting.
Ok brain wiped.
in javascript is that true of google closure too?
ok understood. So google closure is actually javascript with this extra restriction.
ok… so guessing for closure to do its analysis… it treats goog.require
more like a syntax directive / special form… i.e. at compile time it inspects each file for those so it knows the extents of the project for dead code elimation etc.. This is the sense in which it is a “static require”, right?
i.e. though it might evaluate the require expression as javascript, it does so outside of normal evaluation. (though I guess it could also evaluate it later on at runtime - but if it did they’d likely be a different implementation as the purpose would be different)
Ok…
So I’m assuming you’re going to say that clojurescript also requires (ns foo (:require [foo.bar :as baz])
to be at the top of the file… and that it basically compiles into goog.require
.
gotcha
which means that ClojureScript REPLs are bit of a heroic effort to simulate expecations
So what I don’t understand is what magic you can possibly do to make the require
macro work… i.e. if you need to emit a require at the top of a file.
How would this work:
(if true
(require '[foo.bar])
(require '[foo.baz]))
sorry forgetting require macro is lumo
exactly
I can see how it can work then… as you just start a new file
but as a general rule they don’t break the rules - otherwise CLJS wouldn’t be portable
do you get an error if you use a require inside a condition?
not sure how that would be possible — at least from inside require
itself.
I guess it would need to be handled in the reader/compiler somehow as a special case?
Anyway thanks for the brain transplant 🙂
Is anyone here familiar with React Native and React Dom when used from Rum?
@grounded_sage anything specific? I might help
@roman01la my question is in #cljsrn
Basically on the tail end of getting React Native for Web to be in a usable state
I know nothing about RN for Web. But in Rum there’s no special syntax for JS React components, just call them as if you would do it in JS
Essentially the API of RN4W is designed to reflect RN. That way you can write components that can render on either Web or Native.
I'm just not familiar with RN so I'm not sure how to go about the mounting part as the AppRegistry.runApplication isn't the way it is done on all the CLJS RN examples I can find.
This worked fine for me in reagent.
["react-native" :as react-native :refer (Text View)]))
(def ViewR (r/adapt-react-class View))
(defn app []
[:div
[ViewR {:style {:background-color "red" :height "100%" :width "100%"}
:accessibility-role "main"}.......
But there is no way to adapt the react class without doing frustrating hacks which weren't working for me. So I am going the remove Sablono entirely approach that the Rum RN people do.
I’m using cljs in a nodejs setting. I’m looking for a way to make a synchronous http post request. In my case I’d like to initialize some state with a JWT token at startup (in e.g. a mount defstate). I can only find async versions.. Any ideas?
you could go crazy and use the node child_process
package with spawnSync
to run curl
or so 😉
@grounded_sage looks like you are passing a cljs object directly to a JS fn
Ah ok. Probably something to do with what I did here.
(defn ^:export init []
;; init is called ONCE when the page loads
;; this is called in the index.html and must be exported
;; so it is available even in :advanced release builds
(do
(mount AppRoot)
(.registerComponent AppRegistry "app" (fn [] root-component-factory))
(.runApplication AppRegistry "app" #js{:rootTag (. js/document (getElementById "app"))}))
(js/console.log "init")
(start))
I decided to follow more closely the RN approach and just tear out Sablono with :exclusions
i’m not sure i fully understand DCE in the closure compiler. if I used https://github.com/binaryage/cljs-oops instead of externs files, for example - how does the compiler know what I’m actually using?
@lwhorton string names (generated by cljs-oops) are equivalent to externs, AFAIK externs are not used to help DCE to do a better job, @lee.justin.m just wrote a piece which might be relevant https://gist.github.com/jmlsf/f41b46c43a31224f46a41b361356f04d
I think the part i’m confused about is the new-ish :npm-deps
config, and the “auto resolution” of common node module formats… how the heck does the compiler know what you use and dont use? how does that relate to externs, etc?
Was about to ask a question about using JS in CLJS 😄 Seems I’m the third today at least. There’s a bit riding on this --- I might (finally) be able to use CLJS for a project at work. — so I can use all the help I can get…apologies for any redundancy. Situation is basically I’d like to use 20-30 React components written in JSX and ES6 (and their dependencies) from CLJS using Reagent and Reframe. I’m leaning toward trying out shadow-cljs but wanted to check here regarding any advancements in 1.10 that I might be able to use
another possibility is to use the “double bundle” style https://github.com/pesterhazy/presumably/blob/master/posts/double-bundle.md
if you are trying to use packages that aren’t in CLJSJS already (or not up-to-date enough/broken etc)
That let’s you stick more to your familiar ecosystem. Just have to do a step with webpack
I’m leaning towards using this approach myself going forward (at least for now). Shadow seems interesting, I’m just not sure I want to dive all the way in on that as of now.
I also, like to have a good both clj/cljs setup, I think shadow would be more specific to just cljs
I've been playing with Shadow. It's a very nice experience so far. It essentially just changes the cljs building step. So it can be incorporated into the other build tools if you want to keep using Leiningen and Boot etc.
Shadow can infer externs from them, which is a real advantage over some other approaches relying on the built-in compiler's extern inference.
@devicesfor yes it does its own inference
@alex-dixon the little writeup I did definitely does not include any improvements that may be coming down the pipe from 1.10
can someone point me to an example of using lein w/ a foreign-lib packaged as a umd via node_modules? do I add node_modules to my resource-paths so that I can configure a lib like follows:
:foreign-libs [{:file "node_modules/recharts/umd/Recharts.js"
:file-min "node_modules/recharts/umd/Recharts.min.js"
:provides ["recharts"]
:global-exports {recharts Recharts}}]
@lwhorton I no longer use lein so I don’t really know the answer to your question, but I remember having trouble getting the paths to work and the way I solved it when I was using foreign-libs was to copy the umd builds into a “lib” directory in my source tree and just do it that way. One other thing: you might add a “./” in front of those paths to see if it just works because the compiler documentation has that. Shouldn’t make a difference but…
It’s this exact kind of stuff that makes lein a troublesome tool for me. It’s almost impossible to track stuff down because the way it is all declarative.
im hesitant to use shadow if only because its kind of the new kid and I dont want to be the one to work out the problems
;; CLJ
(clojure.string/lower-case 7)
=> "7"
;; CLJS
(clojure.string/lower-case 7)
#object[TypeError TypeError: s.toLowerCase is not a function]
fine...I've assumed that both of the programs above are incorrect, and that it only accidentally does something in Clojure.
Point 4 in the clojure.string
namespace document is relevant to the above. https://clojure.github.io/clojure/clojure.string-api.html
I don’t understand why I see :scope "provided"
on cljs dependencies. I don’t see a difference either way in my projects. When is it useful?
@jmckitrick By default boot (and I think lein) don't include files from provided scope in uberjar. And the Cljs lib files are not useful in uberjar as Cljs has been compiled into JS.
So it gives me a smaller build. Thanks!
Based on Lein docs, it doesn't care about dependency scopes, but Leiningen profiles, so maybe this doesn't work with Lein.
a long while ago I remember cljs didn’t support runtime resolve
of namespaces, is that still the case?
it’s probably really awkward to do that with how :advanced munges namespaces, right?
when creating a MapEntry
object manually in cljs, should the last param be nil
? e.g. (cljs.core/->MapEntry :a 1 nil)
FWIW, there is a "static" cljs.core/resolve
. You'd need to use self-hosted, and eval
to have a true resolve (Planck has one in planck.core/resolve
)
@nathanmarz Yeah, that is the mutable __hash
field.
If you don't need outright blazing speed, perhaps something like (defn map-entry [k v] (first {k v}))
suffices, without actually having a nice MapEntry constructor
(I don't know what the story is on directly constructing core types... whether the basis parameters are private or subject to change, etc.)
hmm, this is for specter so need it to be as fast as possible
this is for producing a new map entry object with updates to its key and/or value
Yeah, well, the last param to MapEntry
can be nil
. IIRC that's done all over the place in cljs.core
is that just a cache for when the hash does get computed?
Yeah, I think most of the types work that way. It is a cached mutable field that is lazily computed
ok cool, thanks for the help
cljs.user=> (.-__hash (->MapEntry 1 2 nil))
nil
cljs.user=> (.-__hash (doto (->MapEntry 1 2 nil) hash))
1185709346
Oh @nathanmarz If you are going down that path, there are other types that satisfy map-entry?
that you may want to support when updating a key or value: cljs.core/BlackNode
and cljs.core/RedNode
I wonder what you'd do in that case, as they might be entangled with their left
and right
fields. Perhaps you would convert a RedNode
or BlackNode
to a MapEntry
so that you end up with a value that still satisfies map-entry?
but has a new key or value
I suppose you are after the idea of maintaining the shape and type of a structure, unlike clojure.walk/walk
which converts map entries to vectors
yea, those specifics of map entry differences don't matter for specter, my issue was prompted since the behavior of records with respect to mapentry seems to have changed in 1.10
basically converting to a lazyseq when doing a conj onto a record now errors
Yeah. And, I think MapEntry
as a type does exist in 1.9.946, so perhaps such code may not absolutely require 1.10
ah indeed, that's good to know
@nathanmarz What is an example of a conj with a record that fails?
cljs.user=> (defrecord Foo [a])
cljs.user/Foo
cljs.user=> (def f (->Foo 1))
#'cljs.user/f
cljs.user=> (conj f (list :a 2))
Error: :a is not ISeqable
at Object.cljs$core$seq [as seq] (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:4441:8)
at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:7982:26)
at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:8155:29)
at cljs$core$reduce (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:8105:25)
at cljs.core.pr_str.cljs.user.Foo.cljs$core$ICollection$_conj$arity$2 (repl:148:25)
at cljs$core$_conj (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:1637:13)
at /Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:7987:98
at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:7988:3)
at cljs.core.List.cljs$core$IReduce$_reduce$arity$3 (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:10371:29)
at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (/Users/nathan/opensource/specter/.cljs_node_repl/cljs/core.js:8141:13)
that doesn't work in clojure, but it used to work in cljs
yea, it's no big deal
glad that MapEntry is now in cljs
Cool. I've been pondering what use might be found with the new MapEntry stuff. I assume that if nothing else it makes some code that is shared between Clojure and ClojureScript perhaps more uniform.
and makes doing blind walks cleaner
Or whatever you call that aspect: Where you maintain the type of the nested data structure.
doesn't affect that really, since that's already handled one level above that by whatever navigator is operating on the data structure as a whole