This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-20
Channels
- # beginners (61)
- # cider (25)
- # cljsrn (7)
- # clojure (76)
- # clojure-austin (1)
- # clojure-russia (10)
- # clojure-uk (2)
- # clojurescript (96)
- # cursive (12)
- # datomic (38)
- # defnpodcast (9)
- # emacs (24)
- # fulcro (1)
- # graphql (5)
- # hoplon (3)
- # jobs (1)
- # keechma (20)
- # leiningen (4)
- # lumo (5)
- # off-topic (13)
- # perun (6)
- # re-frame (19)
- # reagent (1)
- # remote-jobs (2)
- # shadow-cljs (199)
- # sql (6)
- # vim (7)
$ lein with-profile +cljs run -m shadow.cljs.devtools.cli
=>
exception in thread "main" java.lang.UnsupportedClassVersionError: shadow/build/closure/ErrorCollector has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0, compiling:(shadow/build/classpath.clj:1:1)
ideas?@theasp by default the the websocket uses the url of the page itself + the default port of 9630
@denik hmm I switched to Java9 yesterday. are you on the latest release? maybe that broke older versions which it shoudln’t have
@denik I just published [email protected]
which has class file version 52 again. (actually fixed in [email protected]
, sorry about that)
I'm trying out shadow-cljs and its working great so far. However I'm having problems getting the repl working correctly with cursive. I connect to the nrepl using cursive remote configuration. When i try to load a empty namespace its working ok, but when I load a simple namespace with some requires i get: CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec
@larshelg welcome. that sounds like you are maybe loading a ns
with (:require ["a-string" ...])
as clojure code instead of cljs?
when you connect to Cursive the REPL starts out of CLJ. so everything you eval is eval’d as clojure
either via the command line shadow-cljs watch the-build
or via the REPL itself (shadow.cljs.devtools.api/watch :the-build)
you then need to switch the nREPL connection itself over to CLJS by selecting which build you want to talk to
the nrepl can also completely control the server, that is why it starts out as clojure
colin is working on a REPL rework for Cursive which hopefully makes things a little easier to work with
After running the (shadow.cljs.devtools.api/nrepl-select :server) the repl still complains about not being able to load clojurescript in a clojure repl
which seems weird, since the watch build is running, and everything else seems fine...
@thheller figwheel allows me to set :websocket-url
to <wss://example.com/figwheel>, and the proxy sends that URL to figwheel. This way I don't need to make random ports public and can control access in one spot. I'd like to do the same with shadow-cljs
either way if you set :websocket-url "
and forward /shadow-cljs/*
to host:9630
that should be fine
@theasp [email protected]
lets you configure :devtools-url "
. must be http or https, it will use ws where approriate.
@thheller trying to eval the ns form into the repl I get
CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:
In: [1] val: ((:require [rum.core :as rum] ["d3" :as d3])) fails spec: :clojure.core.specs.alpha/ns-form at: [:args] predicate: (cat :docstring (? string?) :attr-map (? map?) :clauses :clojure.core.specs.alpha/ns-clauses), Extra input
#:clojure.spec.alpha{:problems [{:path [:args], :reason "Extra input", :pred (clojure.spec.alpha/cat :docstring (clojure.spec.alpha/? clojure.core/string?) :attr-map (clojure.spec.alpha/? clojure.core/map?) :clauses :clojure.core.specs.alpha/ns-clauses), :val ((:require [rum.core :as rum] ["d3" :as d3])), :via [:clojure.core.specs.alpha/ns-form], :in [1]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x1f563fb3 "clojure.spec.alpha$regex_spec_impl$reify__2436@1f563fb3"], :value (dashboard.core (:require [rum.core :as rum] ["d3" :as d3])), :args (dashboard.core (:require [rum.core :as rum] ["d3" :as d3]))}, compiling:(/Users/den/Dropbox/dev/code/centriq/centriq-automation/transcription/dashboard/src/dashboard/core.cljs:1:1)
@denik that looks like it might be trying to eval in clojure still. clojure doesn’t support the strings.
hmmm just did a quick test. it seems to connect fine but I can’ get it to eval anything
When using the :npm-module
target (https://shadow-cljs.github.io/docs/UsersGuide.html#target-npm-module), is it possible to somehow embed a REPL server into that outputted JS file? I'm trying to embed it into a create-react-app application, and then connect to it from CIDER :thinking_face:
require("shadow-cljs/shadow.cljs.devtools.client.node")
should do it if you are using the default :output-dir
create-react-app makes things a bit tricky since its using ES6 import
which can’t be conditional
otherwise I’d recommend wrapping the require
in the usual process.env.NODE_ENV
check
Ah ok. Maybe code splitting could help here? https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#code-splitting
https://github.com/thheller/shadow-cljs-examples/blob/master/cljs-react-app/src/index.js
oh wait right .. not the node
thing. require("shadow-cljs/shadow.cljs.devtools.client.browser");
is there a doc somewhere that explains what shadow-cljs is doing? you mentioned transpilation in the other thread. i’ve just gotten my head around why we have externs and how to avoid them with cljs-oops but it sound like shadow is doing something else. (the docs on how to use shadow are great, btw, kudos, i just like to have an idea of what the tool is actually doing)
wrote a whole series about Js dependencies here https://code.thheller.com/
https://code.thheller.com/blog/shadow-cljs/2017/11/10/js-dependencies-in-practice.html
@thheller once I have shadow.cljs.devtools.client.browser
loaded, how would I start a REPL client? Something like: shadow-cljs cljs-repl
?
yes, wrote a whole section about that a few hours ago https://shadow-cljs.github.io/docs/UsersGuide.html#_clojurescript_repl
Hmm...I keep getting this:
[3:1]~cljs.user=> (js/alert "test")
There is no connected JS runtime.
Hm...still no luck. Once I have required shadow.cljs.devtools.client.browser
in index.js
, is there any function I need to call to actually "start" it? Or is the act of requiring it enough?
Here's what I'm working with: https://github.com/cjsauer/perfect-storm'
Looks like maybe there is a flag that must be enabled? https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/cljs/devtools/client/browser.cljs#L329
opened https://github.com/thheller/shadow-cljs/issues/182 … will take a look tomorrow
I wish I understood this sort of stuff better so I could help out 😕 Compilers are still kind of magic to me haha
:npm-module
works ok but the REPL is never going to be reliable anyways given the amount of stuff webpack does to the code
Well, my team is primarily JS guys, and they all use create-react-app. I'm looking for a good way to introduce ClojureScript to the team, but in a really seamless way that doesn't interrupt their workflow too much. I figured if I could at least jack a REPL in, I'd be able to preserve both workflow styles pretty well...
shadow-cljs seems like a really promising tool for integration projects like the ones we face
yeah thats what :npm-module
was supposed to achieve, which it sorta does until you launch a REPL 😉
hehe, I'm excited to see it working. There's some really interesting workflows hiding in the JS/CLJS pairing
REPL definitely works way better when shadow-cljs is in control and its JS doesn’t get rewritten by something else
we’ll see if I can fix it tomorrow. I’m not actually sure it ever worked properly beyond basic (js/alert "foo")
😉
@lee.justin.m I can go into technical details if you’d like. I mostly left those out and focused more on the “why”
@thheller My basic curiosity is that I’m a javascript programmer. Things like webpack and minification and babel all screw with the code and seem to be able to do so without breaking everything. So far I’m a little curious and terrified that certain kinds of innocuous code (.field js/thing)
can be broken so easily. How do other tools do it? So my interest in (1) the practical, which so far has been: use cljs-oops for all external accesses and (2) learn about different approaches people are taking. It seems like you are doing something different in shadow to make interop safer (?). At any rate I just have a general technical curiosity here. No specific burning need.
I don’t recommend using cljs-oops
at all. shadow-cljs has greatly improved externs inference support which has elimitated the need for almost every extern I used before
https://code.thheller.com/blog/shadow-cljs/2017/11/06/improved-externs-inference.html
Regarding this: We only need externs for the code we actually call from CLJS, not everything the JS code uses.
That suggests that over-specifying externs keeps code in that might otherwise be elided. Does GCC do DCE on npm modules? I thought the whole idea is that the compiler won’t do advanced optimizations on npm modules and the externs are a directive to the compiler not to name mangle those symbols in optimized code.
but since shadow now knows more about those interop points due to the requires in ns
and such
the closure compiler will now protect that name whenever it can’t exactly identify which type it is on
it doesn’t really matter i guess but given that the javascript module is going through :simple
optimizations i was think that createThing
couldn’t ever be renamed or removed anyway
but CLJS is still fully :advanced
optimized so it could be removed there (in case it exists)
This great stuff. I’m going to read through your stuff before I ask you any more questions. 🙂
I do have one other question, which is actually about DCE. Do you know if the symbol munging thing is necessary to do DCE? I’ve often wondered if we could just turn on DCE without the symbol munging and get some stuff for free.
the closure compiler has some options that let you fine tune what it does to the code
closure is already pretty good at optimizing ES6. it just struggles with some dynamic CJS things people do
it would be interesting if you could do static analysis on a body of code to try to see if code was already safe for advanced optimization. you’d get a lot of false positives, but it might be able to show you everywhere something dangerous is happening (e.g. string property access)
well you can always set :js-provider :closure
and see if you code still works. that does :advanced
for everything. if it doesn’t go back to :shadow
.
yea it would probably not work in a lot of cases, but it would be awesome if you could use babel or something to provide certainty that a module is safe for compilation
anyway, i don’t even understand what the hell is going on at any level so that’s just a pipe dream
doing what webpack and babel do however seems to be the safest way to deal with node_modules
so I’m doing that
well i’m interested to dig in. so far the safest route for using modules for me has been to use distribution builds with no externs and run all accesses through cljs-oops.
oh i’m not wedded to anything, but cljs-oops is better than relying on some half assed broken not up to date externs file that someone made 3 years ago
better yet use :infer-externs :auto
and let the compiler tell you if it doesn’t unterstand something