Fork me on GitHub
#shadow-cljs
<
2018-08-02
>
mattly04:08:29

ok this is really nice to work with

šŸ‘ 4
lilactown04:08:36

šŸ˜„ we really like it. been using it at work for about 5 months since the start of our project

Schpaa11:08:47

The shadow-CLJS manual is 20000 words long

šŸ˜Ž 12
šŸ˜Ÿ 4
picard-facepalm 4
aw_yeah 4
thheller13:08:09

so much left to add still šŸ˜ž

henrik13:08:48

@thheller Draw a picture. A picture says more than 1000 words. Or even better: upload an interpretive dance! Iā€™m sure that says more than 20000 words.

thheller13:08:50

I wish šŸ˜›

pez15:08:48

Iā€™m having trouble with release building of a node library target. Getting

TypeError: a.Ga is not a function
extensionHostProcess.js:452
    at Object.ih [as greetings_activationGreetings] (/Users/pez/.vscode/extensions/cospaia.clojure4vscode-1.3.33-TS-CLJS/out/lib/calva.js:276:520)
    at activate (/Users/pez/.vscode/extensions/cospaia.clojure4vscode-1.3.33-TS-CLJS/calva/extension.ts:114:14)
I donā€™t get this if I build with compile. What is the most obvious thing I could have missed? I have release building working in another vscode extension project (Calva Formatter) and am trying to use the same build pipeline in Calvaā€¦

lilactown15:08:24

@pez do you have any other JS code on the page? nvm youā€™re using node

thheller15:08:32

@pez if you prefer not to deal with externs you can set :compiler-options {:optimizations :simple} although I do recommend trying :compiler-options {:infer-externs :auto} first

pez15:08:01

Thanks! (I was looking for where functions in my library were not properly exportedā€¦ šŸ˜ƒ ) I could get past the first hurdle by adding a type hint. Now will see if :infer-externs does the trick. I should get less of these problems once I have factored the code better between what I do in TypeScript code and what I do in ClojureScript code.

pez15:08:11

@thheller: I will be moving Calva development to implementing more and more of the ā€œbusiness rulesā€/logic in CLJS and do the integration in VSCode in TypeScript. (Building the whole extension using shadow-cljs worked, but meant that I couldnā€™t use the debugger for all that JS code that still remains to be ported and I canā€™t afford the slowdown in development that that brought.) Anyway, so I will build the logic as a node library using shadow-cljs. Thing is the library API will get pretty ā€œfatā€/have many functions. Since namespacing is dropped, I am now trying with prefixing the function names. Is there a cleaner way, that you can see?

thheller15:08:12

you can use :npm-module so the TS part can import namespace separately when required

pez16:08:06

Wow, seems the convenience mode should work for me.

thheller16:08:30

well not if you plan on deploying the code anywhere

thheller16:08:57

well, if you publish under your own package name that can do it of course

pez16:08:31

The code will be deployed anywhere the Calva extension is installed, so I will have to learn some about building npm modules, I guess. But the name spacing it allows is so much nicer than what I have now, so Iā€™m happy to investigate.

thheller16:08:54

@pez you can just make it part of your calva stuff

thheller16:08:35

its basically just a directory you need. it doesn't have to be entirely separate package

bupkis17:08:22

I'm trying out Cursive. And I decided to also try out :node-script at the same time, since I just want to play around with ClojureScript and Cursive's REPL integration. I've written a minimal shadow-cljs.edn, ran npx shadow-cljs pom, left a running npx shadow-cljs server in a terminal, imported pom.xml into Cursive, connected to the REPL, I am able to do (shadow/watch :the-id) and and then (shadow/nrepl-select :the-id) - Cursive recognizes it at that point as a CLJS REPL. But if I try to evaluate anything - I get "No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript"

bupkis17:08:54

So I guess :node-script isn't the best option for that kind of experimentation, do I really need to switch to :browser and keep a browser running even though I just want to play around with the language itself?

thheller17:08:10

just use (shadow/node-repl) instead

thheller17:08:33

otherwise you need to actually run the node script manually. ie. call node the-script.js

bupkis17:08:48

oh I see. I read that section of the manual, but had a brain fart and didn't think it applies to me. In that case I don't even need to tell shadow to watch the app, since I'm sending code to the repl via cursive and not running the compiled output, right?

thheller17:08:32

node-repl doesn't watch yes. :node-script does.

bupkis17:08:45

REPL command timed out

bupkis17:08:07

let me restart Cursive just in case

thheller17:08:15

what command?

bupkis17:08:37

just what Cursive output when I told it to switch the REPL namespace to the current file's one

bupkis17:08:01

and shadow-cljs shows [:did-not-find myns.core]

bupkis17:08:24

Just to be sure I'm doing it right: generate pom, import pom into cursive; start shadow-cljs server; start cursive nrepl connection; issue (shadow/node-repl) - at that time cursive shows that it is in CLJS repl. but then setting the REPL namespace fails

thheller17:08:36

did you require it first?

thheller17:08:09

yeah I can reproduce with (in-ns 'ns.that.wasnt.loaded-yet)

thheller17:08:23

guess cursive just sends a blank in-ns

bupkis17:08:52

I tried loading the file in the repl (via Cursive's REPL / Load file in REPL) and got the following:

bupkis17:08:29

Loading src/myns/core.cljs... repl/require failed { Error: ENOENT: no such file or directory, open '/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/clojure.set.js'
    at Object.openSync (fs.js:443:3)
    at Object.readFileSync (fs.js:348:35)
    at global.SHADOW_IMPORT ([stdin]:45:15)
    at Object.shadow$cljs$devtools$client$node$closure_import [as closure_import] (/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:33:4)
    at Object.shadow$cljs$devtools$client$node$repl_require [as repl_require] (/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:61:7)
    at shadow$cljs$devtools$client$node$process_message (/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:122:6)
    at Object.shadow$cljs$devtools$client$env$process_ws_msg [as process_ws_msg] (/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/env.cljs:148:10)
    at WebSocket.<anonymous> (/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:159:12)
    at WebSocket.emit (events.js:182:13)
    at Receiver._receiver.onmessage (/Users/bupkis/dev/myns/node_modules/ws/lib/WebSocket.js:141:47)
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path:
   '/Users/bupkis/dev/myns/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/clojure.set.js' }
done

bupkis17:08:11

if I require it manually in the REPL - loading the file afterwards works fine

thheller17:08:04

not a clue whats happening. the recent nrepl change seems to have messed up something on my side and I can't use nrepl anymore

thheller17:08:10

god dammit I hate nrepl so much

bupkis17:08:37

I wonder if connecting from Cursive to the socket-repl with something like tubular would be better

bupkis17:08:44

not sure if Cursive supports socket repl at all

thheller17:08:13

you can create a clojure.main config and set parameters to -m shadow.cursive-repl

bupkis17:08:21

but tubular goes around that

thheller17:08:31

that will automatically connect to the running shadow-cljs server

bupkis17:08:41

let me try that

thheller17:08:40

[2:1]~cljs.user=> (require 'demo.script)
nil
[2:1]~cljs.user=> (in-ns 'demo.script)
nil
[2:1]~demo.script=> 

thheller17:08:46

this works for me. thats all I know šŸ˜›

bupkis17:08:52

yeah if I require it first, then load-file works

bupkis17:08:07

btw. the clojure.main with -m shadow.cursive-repl raises an exception

thheller17:08:02

the only interesting bit is missing šŸ˜›

bupkis17:08:12

yeah just noticed cursive didn't copy it

bupkis17:08:18

had to expand manually

bupkis17:08:23

at java.util.Formatter.checkText(Formatter.java:2579)
	at java.util.Formatter.parse(Formatter.java:2565)
	at java.util.Formatter.format(Formatter.java:2501)
	at java.util.Formatter.format(Formatter.java:2455)
	at java.lang.String.format(String.java:2940)
	at clojure.core$format.invokeStatic(core.clj:5684)
	at clojure.core$format.doInvoke(core.clj:5678)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at shadow.cursive_repl$get_socket_port.invokeStatic(cursive_repl.clj:25)
	at shadow.cursive_repl$get_socket_port.invoke(cursive_repl.clj:10)
	at shadow.cursive_repl$repl.invokeStatic(cursive_repl.clj:31)
	at shadow.cursive_repl$repl.invoke(cursive_repl.clj:29)
	at shadow.cursive_repl$_main.invokeStatic(cursive_repl.clj:93)
	at shadow.cursive_repl$_main.invoke(cursive_repl.clj:87)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)

thheller17:08:18

hehe oops. never had that error so I never noticed

thheller17:08:32

are you in the correct directory? and is the shadow-cljs server instance running?

thheller17:08:50

the error above is just a missing .shadow-cljs/socket-repl.port file which should exist when the server is running

bupkis17:08:59

yes the file is there and the port is the correct one. the run configuration for that clojure repl has the working dir set correctly

thheller17:08:51

oh hehe . that script is really old

thheller17:08:08

you can set :cache-root ".shadow-cljs" in your shadow-cljs.edn

thheller17:08:19

I'll modernize the script a bit

bupkis17:08:21

yeah that works

bupkis17:08:50

but I think I'll stay with the nrepl way and manually requiring the NS before trying to load the modified file in the repl

bupkis17:08:58

the autocomplete is busted in the cursive-repl mode

bupkis17:08:04

but that's probably cursive's fault

thheller17:08:20

I'll try to figure out what happened to my nrepl stuff

thheller17:08:28

then I can test whats actually going on

bupkis17:08:07

I know you're busy so no worries, the node-repl thing is a working solution

bupkis18:08:01

btw. is :node-script the best way to do what I'm trying to - e.g. to have a live repl in Cursive that I can load files into and play. It's not a problem to run some Node process manually outside of Cursive if need be, I'm already running the server so one more won't hurt hehe

thheller18:08:55

no node-repl is better for that

thheller18:08:25

unless you also want the node script to actually do something itself

thheller18:08:34

if you just want the REPL then node-repl

bupkis18:08:42

thanks šŸ™‚

lilactown18:08:58

thheller, how hard do you think it would be for someone to carve out a pared down version of shadow-cljs that just built code? as in no watcher, repl, etc.

lilactown18:08:54

I think it would be very useful for running on e.g. a toaster jenkins or gitlab runner

thheller18:08:10

whats wrong with shadow-cljs compile?

thheller18:08:20

that doesn't start any watchers or anything?

lilactown18:08:12

IME when running on CI, starting the shadow-cljs process to run shadow-cljs release app takes the majority of the time spent on that task

lilactown18:08:26

thinking of ways to optimize the startup time

thheller18:08:37

you never reported back with any actual startup times

thheller18:08:53

did you address the caching issues?

lilactown18:08:55

I did address the caching issue, and that sped up the building of the code itself a bit. but the startup can still be in the ~3-5 min range

thheller18:08:25

do you have shell access to the box running the stuff?

lilactown18:08:37

obviously it gets worse the more jobs that are running. weā€™re working on getting beefier CI servers and some other enhancements

lilactown18:08:05

probably not; itā€™s a docker container running Iā€™m-not-sure-where tbh

thheller18:08:27

are you using deps.edn yet?

lilactown18:08:02

not at work, no. weā€™re using leiningen, but I didnā€™t notice any changes between using regular shadow-cljs and the leiningen integration

thheller18:08:48

before you try to optimize anything in the dark you should really gather some data first

lilactown18:08:14

agreed. Iā€™m on my day off and thinking of hare brained ideas šŸ˜›

thheller18:08:41

launch a blank lein repl and then (time (require 'shadow.cljs.devtools.api))

thheller18:08:55

if that actually takes 3-5min we can talk about tuning that

lilactown18:08:09

I can tell you that running the container locally on my 16gb macbook, the build times are completely reasonable

thheller18:08:57

5min seems pretty excessive to load some code

lilactown18:08:41

but not joking I have time npx shadow-cljs release <builds> running on our CI and I easily see ranges from 5-10mins

thheller18:08:08

I totally believe you but I would still like to see a npx shadow-cljs release <builds> --verbose report

thheller18:08:26

I need to know WHERE the time is spent before thinking about optimizing anything

thheller18:08:48

there is a lot of stuff happening even on startup

thheller18:08:00

so it could be the classpath indexing just being terribly slow

lilactown18:08:11

totally. Iā€™ll gather some data and report back early next week

lilactown18:08:23

my main task for this sprint is improving our CI šŸ™ƒ so if thereā€™s some low hanging fruit I can grab once we know more Iā€™ll be happy to do the work

thheller18:08:34

so if you cache only .shadow-cljs/builds you might want to add .shadow-cljs/jar-manifest

thheller18:08:54

but again ... without any data this is impossible to make suggestions for

thheller18:08:04

assuming you actually fixed the cache issue

lilactown18:08:06

we are persisting .shadow-cljs/builds and node_modules at the moment - not sure about jar-manifest. I canā€™t remember if I only kept the builds folder or the whole .shadow-cljs

lilactown18:08:13

Iā€™ll check on monday šŸ‘

thheller18:08:38

its only a guess. also the disk performance really matter. just the other day @caleb.macdonaldblack changed something in his container setup to go from 3sec+ recompile times down to 0.3secs

thheller18:08:56

so thats another thing to look out for

thheller18:08:27

but really run with --verbose. the output prints just about everything where any time is spent

thheller18:08:52

well its probably still missing a lot of details but it should help

daviwil18:08:26

@thheller new here, just wanted to say thanks for all the work you've done on shadow-cljs! I've been waiting so long for a viable dev setup for working with ClojureScript in a "normal" JavaScript project

metal 12
thheller18:08:05

welcome. glad you like it.

daviwil18:08:06

it's a relief to not have to deal with leiningen for a project that doesn't use any Clojure code on the JVM

daviwil18:08:10

Has anyone been able to set up rebel-readline in the shadow-cljs REPL? Not sure if it's incompatible with how shadow-cljs works, but it'd be awesome to have that readline experience

thheller18:08:24

I have not looked at it yet. the CLJ repl should work out of the box. no idea how to hook up the CLJS REPL though

daviwil18:08:43

Yeah, that's the part I wasn't sure about

thheller18:08:50

I always recommend hooking up your editor first. I only use the REPL from Cursive the readline was never important to me

daviwil18:08:25

I've gotten shadow-cljs to work with Calva in VS Code, but the REPL experience isn't that great there. I'll try setting it up with ProtoREPL next

daviwil18:08:14

Yep, found that one last night, thanks!

daviwil18:08:49

I suppose I should try to get it working in Atom since I'm a member of the Atom team šŸ˜‰

šŸ˜ƒ 12
thheller18:08:50

feel free to open an issue about rebel-readline

daviwil18:08:14

Yeah, I think I'll try to give it a shot and set up a demo repo if I can get something working

thheller18:08:15

the question has come up multiple times now so if there is an issue I maybe won't forget about looking at it at some point šŸ˜‰

pez18:08:45

@daviwil: as the author of Calva, Iā€™d like to know what about the REPL experience isnā€™t great in your opinion. I have tons of ideas of where to focus my efforts, but time is limited and knowing what would make people stick with Calva is gold. #calva-dev is a good place to talk about these things. šŸ˜ƒ

daviwil18:08:17

Hey! Sorry I didn't give more context to what I meant there. What I didn't say is that I'm really impressed with the overall setup experience of REPLs in Calva, worked super smoothly in my experience

daviwil18:08:17

The one thing that surprised me is how the CLJ and CLJS REPLs appear in different terminal items, I actually didn't know they were there until I clicked into the dropdown

daviwil18:08:23

That may be a mistake on my part, though

daviwil18:08:18

I've tried different Clojure(Script) extensions in VS Code in the past and Calva is the only one that worked for me first try, so kudos for that!

pez18:08:14

The terminal API:s are very limited. I am thinking about doing something with some ā€œspecialā€ text files. A bit like how it seems to be implemented in Emacs/CIDER.

daviwil18:08:24

Yeah, definitely. I am the original author of the PowerShell extension which is also heavily REPL-driven. They seem to be making progress on getting a WebView extensibility API online so that you can do custom UI panes. That might be an opportunity to make a ProtoREPL-like REPL UI for your extension šŸ™‚

pez18:08:30

I do hope many people get it working first try.

thheller18:08:31

@pez you still can't do custom UI in vscode right? last time I checked it wasn't possible to add anything custom besides a weird previewHTML trick

daviwil18:08:47

Lemme see if I can find the APIs they were adding for that

pez18:08:35

@thheller: It is very limited.

daviwil18:08:48

Looks like the WebView APIs made it out of "experimental"

thheller18:08:19

webview would be pure gold

daviwil18:08:37

I wish their API docs were more linkable šŸ˜•

daviwil18:08:54

Search for createWebviewPanel

daviwil18:08:35

Downside is that it has to be in an editor column, not in the terminal/output panel area

thheller18:08:02

hmm that might still be useful though

daviwil18:08:12

Yeah, I think you'd be able to do a lot with it

thheller18:08:24

so the current proof of concept is reachable under assuming you have a shadow-cljs server running

daviwil18:08:24

I think it allows you to send messages to the JavaScript loaded in the WebView

thheller18:08:36

the idea is to build a UI for shadow-cljs including REPL stuff

thheller18:08:46

editors could then just host the page in a webview

daviwil18:08:56

That'd be amazing

thheller18:08:57

and boom you have a full UI for CLJS in your editor

thheller18:08:11

atom, cursive would support this today. looks like vscode might too

daviwil18:08:18

Then maybe I could make a shadow-cljs extension for Atom very easily šŸ™‚

thheller19:08:42

that UI idea has been brewing for soo long now I should really just start working on it šŸ˜›

daviwil19:08:29

Nice! I see the REPL page at that uri

thheller19:08:42

input at the bottom has parinfer active

pez19:08:42

The editor column has become more viable with the addition of the grid layout.

thheller19:08:46

shift+enter to execute

daviwil19:08:12

Thanks! I was just about to ask how to execute because Ctrl+Enter wasn't working

daviwil19:08:24

this looks great

daviwil19:08:43

Ooooh yeah, I was wondering if they had some conceptual docs for it

thheller19:08:01

although it appears to only support local html and no url for the document itself

daviwil19:08:59

Could it be possible to include a simple html/js file combo with the extension that can link up to the REPL server?

daviwil19:08:11

not ideal, but should be possible

thheller19:08:20

it seems to allow loading resources from urls so just a simple html with <script src=""> or so might do it already

thheller19:08:39

well gotta build the UI first anyways šŸ˜‰

daviwil19:08:52

true, true šŸ™‚

daviwil19:08:58

exciting possibilities, though

richiardiandrea18:08:31

about to add select-nrepl support in cider šŸ˜‰ feel free to try it out https://github.com/clojure-emacs/cider/pull/2397

richiardiandrea19:08:31

about the above, I wonder whether a watch-all could be a good idea ...

daviwil23:08:55

Timing out for me too

thheller23:08:34

the domain is maintained by @jiyinyiyong and hosted in China