This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-12
Channels
- # aleph (10)
- # beginners (62)
- # boot (12)
- # cider (97)
- # cljs-dev (171)
- # clojars (1)
- # clojure (224)
- # clojure-italy (4)
- # clojure-nl (2)
- # clojure-russia (1)
- # clojure-spec (41)
- # clojure-uk (68)
- # clojured (7)
- # clojurescript (115)
- # community-development (4)
- # cursive (2)
- # data-science (1)
- # datomic (18)
- # duct (40)
- # emacs (1)
- # events (1)
- # fulcro (148)
- # funcool (2)
- # graphql (2)
- # immutant (3)
- # jobs (3)
- # keechma (1)
- # luminus (2)
- # numerical-computing (1)
- # off-topic (19)
- # om (6)
- # parinfer (10)
- # pedestal (15)
- # precept (86)
- # reagent (12)
- # ring (3)
- # ring-swagger (2)
- # shadow-cljs (42)
- # spacemacs (19)
- # specter (17)
- # sql (11)
- # tools-deps (78)
- # unrepl (62)
- # vim (28)
I'm trying to use cljs.js in a fairly naive way to have a bootstrapped repl, and what I'm seeing is that after I do a require, even though it appears everything succeeded, it still doesn't "know about" the loaded namespace. I can actually access vars and values, bu I get a warning in the JS console about using an "undeclared Var". Does this sound like any kind of specific mistake I'm making with cljs.js to anyone ?
I see this: https://github.com/clojure/clojurescript/wiki/Custom-REPLs#eliminating-loaded-libs-tracking
It's surprising how challenging it has been to figure out how to build a simple embedded repl. Lots of stumbling blocks.
@pmooser Interesting. I’ve actually not looked at cljs.core/*loaded-libs*
behavior in self-hosted, focusing mostly on cljs.js/*loaded*
.
It's really not terribly clear (at least to me) exactly what the minimal required setup is to get a repl that doesn't break like this in subtle ways. I don't even receive the exception when the underlying closure library doesn't load the library - I only saw it because I had a breakpoint.
Are you using the load-fn? 99% of the times the problem is in the things you return from it in my experience
I've tried using load-fn, and also (when trying with replumb) the read-fn equivalent. It looks like I'm expected to patch the google closure loading code to not throw if we load something more than once.
Not clear what you are referring to here .. can you expand some more? Maybe I am missing something. Are you requiring node modules? Is it a shareable project?
No, unfortunately it's a proprietary work project, and it's not feasible right now to extract an independent case that can be reproduced.
@mfikes I've tried to look at cljs.js/loaded but I'm often seeing it not update after a require that 'appears' (to me) to be successful, but I suspect it's all due to this same issue, at least for now.
@pmooser Are you retaining the result of (cljs.js/empty-state)
in a var and reusing it between evals?
@pmooser Ahh, yeah, I wrote this based on that about 3 years ago https://github.com/mfikes/planck/blob/master/planck-c/engine.c#L285
Ah, sadly, it complains that CLOSURE_IMPORT_SCRIPT is undefined. That's what I get for traipsing around in code I don't understand at all. 😞
Keep going! I think it took me 2 weeks to finally get Ambly working, and I think I gave up 3 times during the process. 🙂
It has been so long, archeology of the code is all I have: https://github.com/mfikes/planck/blob/master/planck-c/engine.c#L242
Heh, well thank you for the references and the encouragement! I am sure this is the right direction.
There have been more humans to have walked on the moon than have created REPLs from cljs.js
, so…
Are you using the load-fn? 99% of the times the problem is in the things you return from it in my experience
say I have a function that returns a native JS Promise (`#object[Promise [object Promise]]`). I want this function still returning a promise, but I want the value that this promise resolves to, to be cljs-friendly (js->clj, keywordized keys etc). Can this be done?
@fbielejec Add a .then callback to the promise, converting all you want to do in there?
Has anyone noticed in ClojureScript 1.10.x that cyclic dependencies aren't being detected?
@olical This was also an issue in 1.9 with parallel build, maybe in 1.10 the default is to build in parallel
fyi
(ns user
(:require
[ :as io]
[clojure.tools.namespace.dependency :as namespace.dependency]
[clojure.tools.namespace.find :as namespace.find]
[clojure.tools.namespace.parse :as namespace.parse]))
(def root (.getCanonicalPath (io/file ".")))
(defn source-root-for [x]
(io/file root x))
(defn throw-if-circular-dependencies!
"Throws an exception if the project has a circular dependency, at the specified source path."
[]
(let [project-graph (atom (namespace.dependency/graph))]
(->>
(namespace.find/find-ns-decls-in-dir (source-root-for "src") namespace.find/cljs)
(map (fn [decl]
{:name (namespace.parse/name-from-ns-decl decl)
:deps (namespace.parse/deps-from-ns-decl decl)}))
(map (fn [{:keys [name deps]}]
(doseq [dep deps]
(swap! project-graph namespace.dependency/depend name dep))))
doall)
true))
@olical you can also try if https://github.com/clojure/clojurescript/commit/56c774be6227d51f4aa3a52571cb2640c7325db7 fixes it
Morning, excellent ClojureScripters; I’m trying to debug a weird, an I’m having trouble even building an intuition about where to look. Goes like this: when I build my CLJS with :optimizations :none
, my CLJS bundle is trying to look for its extra js modules (i.e. base.js
, cljs_deps.js
) in a path that’s mutated depending on the route requested. So, if I request, say, /about
, everything works fine; if I request /monkey/about
, /monkey
is now prepended to the asset path, and everything breaks.
What are the odds that someone else has seen this, or built this particular footgun for themselves before?
(My casual guess is that I have done something really clever, but I’m still deeply in the “what even” phase of trying to figure out what.)
@byrongibby Does your asset-path starts with a /
?
I’m serving a CLJS single-page app from a CLJ server using http-kit; I have no idea if it’s possible some other thing is prepending bits to incoming requests.
The fact that it only works at the root of your paths makes me think it is an issue of relative URI in the asset-path. I would look at the paths of your <script>
tags in the html when you visit /monkey/about
. You will also have to recompile the ClojureScript once you change the asset-path.
With script tag: <script src="/js/compiled/voltron.js" type="text/javascript"></script>
I still see requests coming in for {:* "/monkey/js/compiled/out/cljs_deps.js"}
This is perfectly dynamic, you understand. If I now try to hit /i/am/the/walrus
, I see {:* "/i/am/the/walrus/js/compiled/out/cljs_deps.js"}
It's clearly not generating the right JavaScript paths. I would look at the build options you use until you can see the right paths being injected in your html file.
I am indeed doing that! I am just… at a loss… for what could possibly be going wrong.
:compiler {:main voltron.core
:asset-path "/js/compiled/out"
:output-to "resources/public/js/compiled/voltron.js"
:output-dir "resources/public/js/compiled/out"
:optimizations :none
:source-map true
:source-map-timestamp true
:preloads [devtools.preload]}}
What I don’t understand is why the CLJS compiler would have dynamic asset paths at all.
I encountered the same issue a few days ago. Putting an absolute path in :asset-path
fixed it for me. I was calling the cljs.build.api/build
function directly though. Is it possible that whatever compilation tool you're using is fiddling with this parameter? Unlikely but who knows... Otherwise I'm out of ideas, sorry.
Gads, I hope not. I’m using the lein cljsbuild
plugin. Can go see if I’m using a current version.
…..okay…. so a thing that makes this make even less sense is that my compiled JS is using absolute paths:
if(typeof goog == "undefined") document.write('<script src="/js/compiled/out/goog/base.js"></script>');
document.write('<script src="/js/compiled/out/goog/deps.js"></script>');
document.write('<script src="/js/compiled/out/cljs_deps.js"></script>');
I'm trying to get how the cljs repl works exactly (and when/where things are done). So, would this be accurate?
+
host | JVM
|
+---------------------------------------+
|
read |
+ |
| |
v |
expand tagged |
literals |
+ |
| |
| |
+-----------------> macroexpand
| +
| |
| v
| analyze
| +
| |
| v
| emit
| +
| |
| |
eval <-------------------+
| |
| |
v |
print |
|
+
@kurt-o-sys everything is on JVM side, only eval
is on the host
ok, thx! What still confuses me are the tagged literals: they are expanded - not sure if I should call it like that - by plain functions (data readers). So, that's also on the JVM. Are they the same as/similar to edn tagged elements? If I'm not mistaken, edn custom tag parsers must/can be implemented on the platform they are read?
hello everyone, what's the easiest way to to add twitter bootstrap to a reagent project?
@joelv I don’t think you need to do anything special. Just include the css and JS from a cdn using a script tag and start using it.
@dnolen the REPL is actually more like a 'read-compile-eval-print-loop'?
@kurt-o-sys basically everything is JVM
right - trying to warp muy wrap my head around it, I'm getting close 🙂.
oh, eval=compile, but eval != macro-expansion?
the only big picture difference is that Clojure can load some byte code into the JVM, ClojureScript has to send source to a JS engine
so, all after reading is eval, so macroexpand is part of eval, right? And macroexpand is ran on the JVM (since that's clojure code, not clojurescript)?
well yes … but it’s ClojureScript too, the whole compiler can compile itself into JavaScript
ok, that makes sense (mostly). I just stick with eval is partly ran on the JVM (macro's) and partly on the host (code after macro-expand), not taking into account cljs-in-cljs.
ok, thx! That'll do.
(and maybe I should rename 'eval' with 'execute' or so?)
ok. simplified: eval = macro-expand + js-eval|eval-cljs|evaluate-form
(or something)
right!
thx! that clarifies it all.
@mfikes @dnolen You were looking for feedback on ClojureScript 1.10.145 (and the previous version). I think it is worth mentioning in the release notes that taking a val
of something that didn't come from a map no longer works and causes an error. I had that bug in my code and it manifested itself after upgrading ClojureScript from 1.9.946.
I'm so glad I have client-side exception logging implemented (along with source map decoding on the server).
It undoubtedly is, but it seems that ClojureScript 1.9.946 tolerated it, while newer versions do not. I'm not disputing the bugness, I just think it's worth mentioning.
Yeah, there is other incorrect code that ClojureScript 1.9.946 accepted. Another example is https://dev.clojure.org/jira/browse/CLJS-2476
And I'm quite happy with the new ClojureScript version, mostly because it includes a newer Closure Compiler, which implements the "@noinline"
annotation. Thanks to this, I was able to nicely macroize Font Awesome icon paths and include SVG only for those icons that I actually use, in an efficient manner. Rather Awesome, if you ask me.
@jrychter Thank you! Incorporated your feedback https://github.com/mfikes/clojurescript-site/commit/6be0febccc732d2b01ae894161729caef4913f5a
@jrychter You mention macroize... I wonder if :closure-defines
and DCE works in that case. (Mostly curious, no need to try; just thinking about the side-effecting macros making code no longer cache-friendly. This works in "project" code, but can cause an issue if it is put into a JAR.)
(Referring to the note near bottom of https://github.com/mfikes/clojurescript-site/blob/issue-183/content/news/2018-03-12-shared-aot-cache.adoc)