This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-08
Channels
- # aws (9)
- # beginners (69)
- # boot (14)
- # cider (26)
- # cljs-dev (56)
- # cljsrn (9)
- # clojars (4)
- # clojure (229)
- # clojure-brasil (1)
- # clojure-france (11)
- # clojure-greece (2)
- # clojure-italy (4)
- # clojure-mke (6)
- # clojure-serbia (6)
- # clojure-spec (83)
- # clojure-uk (38)
- # clojurescript (171)
- # core-async (3)
- # cursive (11)
- # data-science (11)
- # datomic (27)
- # emacs (113)
- # funcool (6)
- # hoplon (4)
- # jobs (1)
- # luminus (13)
- # lumo (44)
- # off-topic (148)
- # onyx (5)
- # overtone (1)
- # pedestal (4)
- # powderkeg (1)
- # proton (2)
- # re-frame (150)
- # reagent (16)
- # ring-swagger (43)
- # spacemacs (4)
- # specter (36)
- # vim (4)
- # yada (10)
Is it possible to compile a single cljs file to a single js file that does not require goog.base?
@iku000888 I believe compiling in :advanced
mode, and perhaps :whitespace
mode, will produce a single file, which inlines any goog.base deps into a single js file.
:main sounds like the trick! Will give it a try. (I did :advance and I was still seeing the goog.* stuff showing up). Thanks!
No prob. See here for more info: https://clojurescript.org/guides/quick-start#less-boilerplate
and note that in project.clj
you do not need to prepend the main namespace with an apostrophe
I see maven central doesn't have any releases for org.clojure/google-closure-library
since june 2016; will that be updated eventually?
There's a pretty serious bug in the goog.math.Integer
class.
@iku000888 I believe that's normal. Always there.
@gfredericks I would advise to bring it up in #cljs-dev or JIRA
@anmonteiro thanks, didn't know about #cljs-dev
@iku000888 np! Have fun 🙂
What is the best way to introspect a
#object[HTMLCollection [object HTMLCollection]]
?Hey, how can I make the functions say_hi
and say_hello
js functions that I can call in node?
(ns my-ns.core
(:require [cljs.nodejs :as nodejs]))
(nodejs/enable-util-print!)
(defn main [& [a name]]
(case a
"hi" (say_hi name)
"hey" (say_hello name)
(println "Nothing"))
{"a" 1})
(defn ^:export say_hi [name]
(println "Hello World!"))
(defn ^:export say_hello []
(println "I said"))
(set! *main-cli-fn* main)
;;(set! (.-say_hi main) 'say_hi)
To do something like
node -e 'var my-package = require("./target/js/milia.js"); my-package.say_hello()'
@urbanslug that looks right to me
lol why did I even bother leaving out the name if I was going to leak it on the require. OpSec fail
@urbanslug this might work for you https://github.com/thheller/shadow-devtools/wiki/ClojureScript-for-node.js-libraries
the issue with the (set! js/module.exports ...)
hack is that it doesn't work in :none
. so it will be slower during development
OK forgive my total newbiness here but I can't figure out in the set!
way of doing things shouldn't this work?
(ns milia-wrapper.milia
(:require [cljs.nodejs :as nodejs]))
(nodejs/enable-util-print!)
(defn main [& [a name]]
(case a
"hi" (say_hi name)
"hey" (say_hello name)
(println "Nothing"))
{"a" 1})
(defn ^:export say_hi [name]
(println "Hello World!"))
(defn ^:export say_hello []
(println "I said"))
(set! js/milia-wrapper.milia.exports {:say_hello milia-wrapper.milia/say_hello})
and I should be able to do something like this
node -e 'var milia = require("./target/js/milia.js"); milia.say_hello()'
but still say_hello is not a fn@urbanslug only module.exports
is recognized by node when using require
So node -e 'var milia = require("./target/js/milia.js"); milia.exports.say_hello()'
(set! js/milia-wrapper.milia.exports {:say_hello milia-wrapper.milia/say_hello})
that part
but even then it won't work in :none
, that is because node expects one file per require
but CLJS is split into many files in :none
@thheller hmmm
(set! js/module.exports {:say_hello milia-wrapper.milia/say_hello})
won't work for me using
node -e 'var milia = require("./target/js/milia.js"); milia.say_hello()'
even with optimization being advanced I guess I'll just try the way that you pointed out and figure out why Nolen's method isn't working for me later,@thheller hmmm so I have to use your build tool to get/use the :exports in my project.clj
I upgraded my project to [org.clojure/clojurescript "1.9.521" :scope "provided"]
. Now a (let [{:keys [a b] :as full} (my-own-function)] (prn full))
prints {[:a "a's value"] [:b "b's value]}
rather than {:a "a's value" :b "b's value"}
. Did destructuring change?
I checked the final value of (my-own-function)
by printing it before returning it, and it looks just fine, that is, {:a "a's value" :b "b's value"}
, and is then magically converted by the destructuring or let or something.
@reefersleep what version did you upgrade from?
Here's a simplified example:
(let [{:keys [hey girl] :as full} {:hey "yo" :girl "dude!"}]
(prn hey)
(prn girl)
(prn full))
nil
nil
{[:hey "yo"] [:girl "dude!"]}
nil
cljs.user=> (let [{:keys [hey girl] :as full} {:hey "yo" :girl "dude!"}]
#_=> (prn hey)
#_=> (prn girl)
#_=> (prn full))
"yo"
"dude!"
{:hey "yo", :girl "dude!"}
nil
^ in Lumo, which is running 1.9.521
right, my suspicion is you have an old analysis cache that you need to clean
I've no idea what's going on 🙂
I guess the first thing to try is to restart Emacs, I'll give it a go.
that’s not gonna do anything
@reefersleep this is unrelated to Emacs. Try do delete your output directory and restart your build
I'll try that. (I had restarted the repl, which runs figwheel, but not deleted the output dir, and I can see why you suggest that 🙂 )
Yeah, the point of the analysis cache is to make your compilation times faster even if you restart the REPL
I'm unsure of what I'm looking for. Tried mv'ing public/js/out
to out.bak
, which prompted the build process to create a new out
folder, but this did not make any difference.
the typical issue is that the cached partially compiled code mixes with the new code in an unexpected way that creates nonsense results; the fix to this is to shut down any auto-builder, run lein clean
(or whatever else it takes to completely erase all partially compiled artifacts), and the nrestart the builder
this is commonly a problem after changing dep versions (in my experience)
I'll try that, @noisesmith
note that lein clean
is not gonna do what you expect it to do
@anmonteiro it does for me- because I set up my clean targets to do so, I guess I can’t generalize that
but yeah, the main thing is to destroy all compilation artifacts
having a default config where clean
fails to remove an output of a compiler driven by lein seems like a misconfiguration to me
lein clean
did not do the trick in my case.
I've tried to remove all of those that I could find, lein clean
and re-run figwheel, nothing has helped so far.
Ah, just found a hidden folder I missed
Yes! Finally managed it. /.cljs_rhino_repl/
was the (last?) folder that I needed to remove. Thank you very much, @anmonteiro, @noisesmith and @john !
if that was my project I would add that dir to lein’s clean targets
I don’t like having caches of compiled code that lein doesn’t obliterate when you run clean
I'll run with that! 🙂
wonder how the folder was generated to begin with, it wasn't re-generated when I re-ran figwheel
Hi all, I'm messing with the new :npm-deps
feature and I keep getting errors about transitive NPM dependencies. Currently running with a deps.cljs that looks like this:
{:npm-deps {:draft-js "0.10.0"
:draft-js-import-markdown "0.2.1"
:draft-js-export-markdown "0.2.2"}}
...and I get an error Cannot find module 'react' from '/Users/foobar/node_modules/draft-js/lib'
My project also uses reagent, which is where I'd like to pull the react dependency from. Do I need to declare it as a foreign-lib or something?
@timgilbert you probably just need to specify react
too in :npm-deps
if it’s an NPM peer dependency
currently no way to make it play nice with Reagent if there’s no lib support for it
Ok. I was hoping I could actually just give it :draft-js-import-markdown
and have it pull in draft transitively too
it’ll pull transitive dependencies
Hmm, looks like the NPM dependency tree is broken though
but not peer dependencies
Ah, ok, that makes sense
Is there a similar mechanism to the lein/clojure :exclusions
thing, so I can tell NPM "this will be loaded from elsewhere, don't worry about it"?
if some dep will be provided by other software at runtime, that’s what the :provided scope in project.clj is for
easy fix for someone who has a moment, lein help :sample doesn’t mention the :provided profile, maybe it should?
https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md it’s described in this document
oh - maybe what you are describing is different though
what's the correct way to optionally handle whether someone passed something into & args
? Is it (if (first args)...
or (if (empty? args) ...
or is something with (apply afn stuff args)
supposed to always work? I worry about a nil
being passed in.
I’d test if args is empty - it always wraps all the args in a collection, so if they passed nil you would get [nil]
which is not empty
Which is why I like the (first args)
method, since it returns nil if there is a nil or if it is empty.
that’s your problem though - if something calls (fn [a & args] ...)
with (a 1 nil 2) calling first misleads you
checking if args is empty is reliable though
Thanks @noisesmith
I'm seeing a Delay
deftype and related documentation in the source that references a delay
function, which doesn't appear to exist. Is delay
not yet implemented?
https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/core.cljc#L2064
whats with diff between that and: https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs ?
What's the right way to require/import a closure class (e.g. goog.math.Integer
) so that I can call static methods, refer to static fields, and extend the class to protocols?
I used to have (:require [goog.math.Integer :as int])
and then use int/
for the former cases and goog.math.Integer
fully qualified for the latter
but that feels terrible and has started giving warnings in more recent versions of cljs so I assume there's a better way to do this
hit, I have an endpoint where I can upload a text file with curl like this:
curl -X POST -H "Content-Type: multipart/form-data" -F "file=@/resources/speciesDiffusion.tree"
now I need to send a similar request from a browser, but
(ajax/ajax-request
{:uri (str "" "/continuous/tree")
:method :post
:params {:treefile content}
:handler #(println %1)
:format (ajax/text-request-format)
:response-format (ajax/json-response-format {:keywords? true})})
gives me a (nicely json converted) error response:
[false {:status 500, :status-text , :failure :error, :response {:timestamp 1494279686227, :status 500, :error Internal Server Error, :exception org.springframework.web.multipart.MultipartException, :message Current request is not a multipart request, :path /continuous/tree}}]
so probably the content-type headers is not correctly setI’m sort of surprised this is hard to find, but does anyone know of a good way to configure routing (like via secretary
) for a single-page app (SPA) in a way that can deal with browser refreshes, as well as someone just putting a full URL path into the location bar?
@mikerod I don’t know if there’s something fancier, but what my app does is make sure that any state that should persist across a refresh (or bookmarking, or following a link) needs to be injected into the fragment data of the page
since the data is in the fragment, it doesn’t cause a new load of the page just because you changed the url
because it’s in the fragment, the back button and link sharing etc. are less likely to break
I made a small library that takes edn data and translates to base64 and puts it in the fragment (with a decoder that goes with, of course)
I haven’t even had luck doing a page refresh while attempting to have things after the fragment
@mikerod weird -I have never seen a refresh alter the fragment
I’ve noticed that in an angular app I was able to do refreshes against a fragment and also to directly plug the fragment into the location bar and go
wait, who are you expecting to act on the fragment?
the fragment is for your app, you have to do something with it (in my case I parse it and inject it into the app state)
OK - when my fragment is changed, goog.history definitely gets invoked
that’s what drives my router
I’ve seen accountant
which seems to try to address the overall problem (I think). However, it doesn’t work well for someone to manually put the location in the location bar and go (or I don’t know how to use it right if it does)
I just hook the my router into goog.history and then parse data out of the fragment… I don’t feel like I did anything that unusual
The main thing I don’t see a clear path forward on is browser refreshes behaving sanely
I think I can get back, forward, and fragment changes to do what they are supposed to
for refresh, I had to make sure that app load propagated state via the same code that the router does
and that no page implicitly relied on state initialized from another page
that plus ensuring that all “bookmarkable” state and state that should be altered by forward / back areas was reified into the fragment data
then you get a mostly-not-broken app
(in terms of url / navigation / refresh)
I should really make a blog post about how we did this
would be interesting to see. I haven’t seen blogs really answering these points for me so far. Been tryign to search quite a bit.
I’ve done this once with secretary but I don’t remember the details (warning this code is 2+ years old): https://github.com/darwin/faceboard/blob/master/frontend/src/faceboard/router.cljs
the trick might be in using goog.History
and https://github.com/darwin/faceboard/blob/master/frontend/src/faceboard/router.cljs#L32