This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-13
Channels
- # aleph (1)
- # beginners (105)
- # boot (6)
- # cider (9)
- # cljs-dev (61)
- # cljsrn (59)
- # clojure (132)
- # clojure-germany (1)
- # clojure-italy (6)
- # clojure-russia (18)
- # clojure-spec (1)
- # clojure-uk (58)
- # clojurescript (56)
- # core-async (1)
- # cursive (17)
- # datomic (20)
- # docs (1)
- # duct (5)
- # editors (1)
- # emacs (7)
- # events (2)
- # figwheel (7)
- # fulcro (30)
- # graphql (8)
- # jobs (3)
- # leiningen (23)
- # luminus (14)
- # mount (6)
- # off-topic (41)
- # onyx (14)
- # protorepl (2)
- # re-frame (7)
- # reagent (32)
- # shadow-cljs (236)
- # tools-deps (92)
- # unrepl (8)
- # vim (60)
- # yada (1)
ok .. seriously ... how can anyone say that clojure is slow ... doing a bit of work with react-native and expo and both are WAAAAAAAAAAAAAAY slower than shadow-cljs. especially when adding the ridiculous amount of time yarn add
takes.
I have a situation where I can build and watch my app and it works in the browser, but can't connect a cljs-repl. It says this when I try to execute something from the prompt:
$ shadow-cljs cljs-repl app
shadow-cljs - config: …shadow-cljs.edn version: 2.2.29
shadow-cljs - connected to server
[1:1]~cljs.user=> (+ 1 2)
No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.
What am I not understanding?what does the browser say? it should say something like shadow-cljs REPL connected
in the console when you load the page
I don't get that message in the console. I get something about some custom cljs devtools formatters not being rendered and then the result of evaluating my app file (a clojure map).
you are running shadow-cljs watch app
. you open whatever that produces in the browser?
I am sorry I am sharing my confusion. But you have the scenario right. Here's my build config:
:builds {:app {:target :browser
:output-dir "resources/public/js/compiled"
:asset-path "/js/compiled"
:modules {:game-of-life {:entries [game-of-life.main]}}
:devtools {:after-load app.main/render!
:http-root "resources/public"
:http-port 8080}}}
My index.html file looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="https://clojurescript.org/images/cljs-logo-icon-32.png">
</head>
<body>
<div id="app">
<h2>Static HTML from index.html</h2>
</div>
<script src="js/compiled/game_of_life.js" type="text/javascript"></script>
</body>
</html>
That explains why the app worked even though shadow-clj said there were compilation errors. 😃 I'll fix and then I might have a Calva version that can handle shadow-cljs projects.
Hmmm, now the cljs repl starts and everything with that is dandy. But Calva still only finds the clj repl, so some more work is needed. But there's a whole weekend ahead to get it done! 😃
you call (shadow.cljs.devtools.api/nrepl-select :app)
to switch the current session over to cljs
Ah, but if I make two clones, maybe I can have both session types? It's a feature of Calva that it is easy to have both connected.
Another question, yesterday you said something about people using cljc files even though they only work in Clojure. What did you mean by that? Or if I misunderstood things completely.
BUT not everyone that uses .cljc
files actually makes sure that they work in both platforms
I see. That is partly why I want Calva to keep both repls available. So that it is easy to switch between them and try make sure they work in both worlds. It has been quite a bother to get tests working in cljs, so we write most of our stuff in cljc.
yeah I tend to test more in CLJ as well. cljs.test
is horrible to use, too many macros.
About clone now. With lein+figwheel I an ls-sessions
and get a vector of sessions w/o cloning. But with shadow-cljs I must first clone to populate the vector. What I would think makes most sense is that the vector is populated to begin with, then I clone sessions that Calva can connect to.
with lein repl
what you are cloning is the repl-y
session which may already have put stuff in the session you don't actually need
I could add a new nrepl op? so you send {:op "shadow-cljs/hello"}
or so. shadow-cljs could reply with something while others will just reply with an error
That would work for me. Better than first testing (shadow.cljs.devtools.api/nrepl-select :app)
and see if that works.
I might start out with jsut letting the user manualy select what kind of session to connect to.
Is it expected that Ctrl-C
on shadow-cljs watch app
sometimes leaves server running, so next time shadow-cljs watch app
doesn’t do anything?
depends on what you mean by server
. https://shadow-cljs.github.io/docs/UsersGuide.html#server-mode
the server instance can be shared, so if you run multiple shadow-cljs watch
only one server
will be used
you run use shadow-cljs clj-repl
(shadow/stop-worker :app)
to stop it if its "stuck"
Hi. I'm trying to get shadow-cljs to spit out a javascript file that is usable for a service worker. I'm re-using the :web-worker true
setting inside shadow-cljs.edn. However, I'm getting the following problem: ReferenceError: document is not defined
(`at hud.cljs:47`) when running the service worker. If this is a bug I'm happy to open a Github issue, just wanted to check that I'm not just doing something stupid.
:web-worker
in a module has a very distinct meaning. it is not suitable for making standalone webworkers or serviceworkers. that should be individual :target
configs
No rush, thanks. I've got it going in pure js for now in any case.
didn't do much with those yet but I think a dedicated framework like https://developers.google.com/web/tools/workbox/ seems to be better
Yeah, that's exactly the library that I'm using now. Was thinking about moving it into clojurescript, but in retrospect you are probably right about just leaving in javascript. The only thing that I was thinking is about using macros to automatically get the list of files to pre-cache from manifest.edn and filesystem (instead of having to run the cli tool), but that is probably just going to overcomplicate things.
@mjmeintjes I'm currently finishing up a target for react-native
. will create simplified ones for worker
after that, then we can properly evaluate whether it makes sense to use cljs for service workers
Sounds great, thanks.
https://clojurians.slack.com/archives/C6N245JGG/p1523608108000180 @thheller initially I was using mount but I also tried a simple fn, saved the file and loaded it in the repl. Should that work?
Hmm, tried that yesterday (several times) and it didn’t work for me. I’ll dig in. Thanks for the sanity check.
I tested by passing :http-handler dev.http/handle
but the ns was demo.http/handle
so I got a NullPointerException`. I added a warning for that.
@thheller do you have a gist you can share? Is dev.http/handle
the full ns or an alias? I’m wondering what I’m doing wrong. Also since I’m using shadow-cljs embedded, is there a way to pass the config in dynamically instead of through shadow-cljs.edn? I’m asking because the library I’m working on (releasing soon) is generating the shadow-config for the user and currently does some ugly macro magic to pretend that there is config when there is none. I wonder if that has anything to do with it.
shadow-cljs watch app
basically calls (shadow.cljs.devtools.api/watch :app)
which calls (shadow.cljs.devtools.api/watch* the-config-map {})
@thheller does watch start it’s own server? I’m currently calling this
(with-shadow-config
(shadow-config config)
(shadow-server/start!)
(shadow-api/watch :app))
yeah sorry. I meant get-or-start-worker
. just take a look at https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/cljs/devtools/api.clj should be easy to follow
and no I do not recommend bypassing the config completely. that is not a supported use case since its waaaaaaaaaaaaaaaaaaaay too much work to account for that.
Thank you. The user can literally pass a regular shadow-cljs config (that is contained in a larger config) so they can still modify shadow-cljs at will but I merge defaults (that can be overridden) and therefore it’s important for me to be able to pass it dynamically.
@thheller something must have been off with lein-checkouts - was still running version 2.2.23 😕 this is absolutely not your fault. However to avoid this in the future, have you thought about printing the shadow-cljs version as the server is started (like in the command line)?
Hello #shadow-cljs, I’m having a lot of fun with this tool. However, I’m a bit stuck while trying to create a macro on a project with browser
target. Is that supported?
what issue are you running into? i dont think shadow (or any build tool) affects the way your code is compiled wrt macros
you certainly want to ensure any .clj files are still in your source-paths
(its a common theme for people to do a /src/clj and /src/cljs
@lwhorton at the moment I’m trying just to do something naive like spitting out some hiccup, I just copy/pasted the example from here: https://github.com/thheller/shadow-cljs-examples/tree/master/macros
i have a strong sense that you have some other configuration issue… i’ve never had issues with macros so long as you write them in a .clj file, and include them in a cljs file
remember that as of 1.7? cljs automatically refer’s macros if both clj and cljs share a name
Call to clojure.core/defn did not conform to spec
-- Syntax error -------------------
(... [{:keys (attrs)} ...] ...)
^^^^^^^^^^^^^^^
has extra input
and
-- Spec failed --------------------
(... [{:keys (attrs)} ...] ...)
^^^^^^^^^^^^^^^
should satisfy
vector?
right, but the only addition was really the defmacro
… let me try to remove it again, one sec
@thheller confirmed, as soon as I remove this code, it compiles again:
(defmacro h1 [props & children]
`[:h1 ~props ~@children])
@thheller hang on, I re-added without the @
and it compiled, it might have been just that
nope, a .clj
at the moment, then I have a .cljs
that require-macro
es it, I’m copying the example from https://github.com/thheller/shadow-cljs-examples/blob/master/macros
nah that was the first macro I attempted to add to this project. But it might be in some of the dependencies… checking now
and bingo! I was requiring tagsoup in that namespace, and that seems to be the root cause of the error.
didn't the error tell you that it was that namespace? it should have. if not thats a bug.
right, indeed it does, although too deep in the stacktrace for me to notice. it’s much easier now knowing what to look for 🙂
feel free to open a ticket with the tagsoup example. should be easy to reproduce when I find some time. the ns causing the problem should be the first thing you see not the last.
is there something fancy I should do to make sure my nrepl connection can attach to a shadow-cljs watch :id
? i’m using vim-fireplace and I can’t seem to make a connectino
@alex340 https://clojureverse.org/t/help-wanted-release-bundle-size-visualization/871/9?u=thheller
i’ve tried using manual :Connect host/port/blah
(vim), and also from a shadow-cljs cljs-repl
using the api/nrepl-select :id
.. but in the first case I get some unhelpful compilation error. in the second case I get cannot read prop 'nrepl_select' of undefined
.
do i have to start a watcher, then a cljs-repl, then connect my browser, then connect to my nrepl?
only need to start the watch, then connect nrepl, then (shadow.cljs.devtools.api/nrepl-select :id)
must be some vim-fireplace issue i’m having. the watcher runs fine, an .nrepl-port file is spit out, and i can even connect a shadow cljs-repl
i don’t see this in the docs anywhere — but does shadow support a local-only profile kind of like leins ~/.lein/profiles.clj?
> You can either configure this in your shadow-cljs.edn config for the project or globally in your home directory under ~/.shadow-cljs/config.edn. its nesteld in there, but could probably use its own sub-section
so .. after much ado (digging through python, nvim support, pip, pyenv, pyvirtualenv) i’ve learned that from my root file /app/
I can invoke :Eval (+ 1 2)
and the nrepl will return 3.
if I go into /app/src/some-mod.cljs
and attempt to Eval
it will always give me a compiler error in the output
it looks like that’s because I can actually eval any code that’s in a .clj file, but not cljs. which I suppose makes sense. I have to “start” the cljs environment via (cemeric.piggieback/cljs-repl :id)
, except when I do that I always get [:no-worker :main]
hmm-- so i’m invoking clj-run build/dev
where my builder does some stuff and ultimately defers to shadow/watch build-cfg opts
so unless there’s something else happening when I use shadow-cljs watch id
, i think it’s running?
I'm a bit confused. You say (cemeric.piggieback/cljs-repl :id)
which would return [:no-worker :id]
not [:no-worker :main]
sorry, i kept trying cemeric but also the shadow-provided api, I’m not sure if they returned different things let me check
leave the custom stuff out of it until that works. impossible for me to tell what you are doing otherwise
separate shadow-cljs server
, then connect to the nrepl, then run /watch :main
spits back “no build with id :main”--
and here’s my config
:nrepl {:port 8001}
:builds {:app
{:modules {:main {:entries [boot.core]}}
...
ok, so now that i’m not being dumb — it spits back :watching
. if from another buffer (cljs); i load the browser to connect to the js environment; I :Eval (shadow/nrepl-select :app)
; now i can eval in my cljs buffer
i know there was a release earlier that made the api/watch <id>
automatically start a server, right? is there something different about that server versus starting it at the command line shadow-cljs server
i wonder?
yes, sorry - my brain is all over the place today. i wonder if using clj-run
to start a task that eventually calls shadow/watch config opts
initializes a server differently
if you are calling a function via clj-run that wants to call watch you have to do this: https://shadow-cljs.github.io/docs/UsersGuide.html#_calling_watch_via_clj_run
i picked up on that a little bit ago while combing through the docs:
(defn dev
{:shadow/requires-server true}
[& args]
(let [c (config/get-build! :app)
build (merge c dev-cfg)]
(move-index (:index-in build) (:index-out build))
(shadow/watch build {:verbose true})))
(def cfg {:index-in "resources/index.html"
:index-out "public/index.html"
:manifest "public/js/compiled/manifest.edn"})
(def dev-cfg (merge cfg {:compiler-options {:closure-defines {'build-tools.constants/graphql-uri (or (System/getenv "GRAPHQL_URI")
so wrt the api/release there’s a release* version that does allow bypassing the get-config! calls
i should have checked (and i thought I did) but there doesn’t seem to be a corresponding watch*
yeah that doesn't exist for watch
since that is slightly more involved when doing things
change that to starter.browser.init("the-actual-url");
and have the init function set it to whatever var
no particular reason, I just wanted to use closure.defines because that’s how i’ve done it in the past. but also you still need to provide that index.html file a dynamic env var somehow
IMHO things like urls aren't actually compile time constants seeing as you are jumping through various hoops trying to get it there
that’s a good idea i’ll look into this. that means I can just spin up a shadow server; nrepl works; the config goes back to being in one place
generating a HTML file that contains the URL should be way simpler than messing with the entire build
of course that means other people who dont want an nrepl now have to startup a server, then start up a watcher