austin
austin copied to clipboard
Client-side projects
Client-side projects don't necessarily have a server component (and shouldn't be required to have one). Take for example the basic tutorial for om: https://github.com/swannodette/om/wiki/Basic-Tutorial That tutorial has instructions for starting a Clojurescript repl in LightTable.
"Type the key chord Control-SPACE to open up the command list. Start typing Add Connection, press enter to select it. In the list of options select Browser (External). Copy and paste the script tag into index.html before the div tag."
And that's all there is to it.
I tried to emulate that tutorial for Austin. I started an Austin repl like so:
(def repl-env (reset! cemerick.austin.repls/browser-repl-env
(cemerick.austin/repl-env)))
Then I looked at the value of
(cemerick.austin.repls/browser-connected-repl-js)
and used it for manual inclusion in the index.html.
I made sure that the cljs source requires
:require [clojure.browser.repl]
Loading index.html does initiates a connection, but errors out with this message:
Uncaught Error: URI file://localhost/robots.txt is invalid for field ppu
Can this be fixed?
If LightTable can do it, I'm hopeful Austin can too.
OK, this thread explains that the problem lies with the Clojurescript repl itself, so not an Austin issue.
http://comments.gmane.org/gmane.comp.java.clojure.user/60605
So what's LightTable secret sauce and how can Austin benefit from it?
Contrary to the official Clojurescript stance that it is not supported, LightTable enables the use case where a html file is opened from disk and successfully establishes a connection with a Clojurescript repl.
Preliminary findings indicate that LightTable fires up an internal web server with websockets transport.
https://github.com/LightTable/LightTable/blob/92ef49faa985d85bad74b131ee46c8977650bc9f/src/lt/objs/clients/ws.cljs
Very interesting. Is this outside the scope of Austin? If so, I'll close this issue. Thanks.
BTW, there is a reward for implementing this: https://twitter.com/swannodette/status/365272360896569344
:-)
Either way, there's a server, something needs to be available to compile the ClojureScript you're evaluating, etc. Given that, what's the benefit of a websocket server vs. HTTP?
Note that Austin just reuses the stock ClojureScript browser-REPL client-side bits, which uses a CrossPageChannel to talk to the server. Changing that isn't necessarily outside of Austin's scope, but (a) it's not a nontrivial change, and (b) the work would necessitate a compelling benefit.
I agee, it doesn't need to be websocket per se.
In this particular instance, I care about the use case, which could be defined like this: "given a client-side project with no server component, start an in-browser Clojurescript repl." This is currently not possible with Austin, but it is with LightTable.
When I was doing the Om tutorial (https://github.com/swannodette/om/wiki/Basic-Tutorial) which contains instructions for LightTable, I was shocked to see how easy it was.
Austin should probably continue to use the stock ClojureScript browser-REPL as-is, but it could provide the additional tooling LightTable has. Whatever the implementation details are, with or without websockets. It's all public, open source code anyway.
There are a couple of things:
- LightTable's approach works because WebSockets are not bound by the same-origin policy. We can modify Austin's embedded server to add the necessary
Access-Control-Allow-Origin: *
header to all responses (or whatever less-permissive one that will allow only localhost and whatever the origin is forfile://
URLs). - This would work with the existing client-side bits, with the exception that the CrossPageChannel (or one of its dependencies) does some questionable URL string-munging in order to (potentially?) check for a
robots.txt
, which ends up yielding an invalid URL (since there's no host in e.g.file:///tmp/start-repl.html
).
I've long wanted Austin to have its own browser-side component to replace cljs.browser.repl
, probably using SSEs instead of the CrossPageChannel (the big advantage of which was that it worked on all browsers, including IE 6, back when CLJS was first released). Combined with the CORS header server-side, this should make austin suitable for this use case.
That all makes a lot of sense. And it sounds like a good plan. If Austin is to become a default go-to REPL for Clojurescript development, it will need to support that use case. I'll be happy to help to the best of ability.
An easier approach would be to allow the user to "mount" a local directory as the root of all resources served for a particular REPL session (mock usage here):
user=> (cemerick.austin.repls/mount-static "/app/directory" ...other REPL env config)
Static local site mounted @ http://localhost:51665/3889/
So /app/directory/index.html
would be served via http://localhost:51665/3889/
or http://localhost:51665/3889/index.html
; similarly for the usual sorts of web resources. Further, Austin could use enlive or similar to inject the necessary JavaScript (equivalent to the output of (browser-connected-repl-js)
) at the end of the <head>
or <body>
tag, populated with the corresponding URL for that session, e.g. http://localhost:51665/3889/repl
.
This would be a much less significant change, but achieve the same objectives…while preserving the ability to have multiple concurrent browser-REPL sessions. Patch welcome.
I agree. I discovered that somebody already proposed something along those lines. Adrian Medina posted a lein template (om-cljs) that has all the machinery required in dev/user.clj.
https://github.com/aamedina/cljs/blob/master/src/leiningen/new/om_cljs/dev/user.clj
I tried it myself and it works great. Austin could borrow from it, no?
Yes, it looks like the approach I described is exactly what was implemented there. So, "borrow", yes, conceptually.
The user in question hasn't submitted a PR themselves, so any kind of copy/paste wouldn't be appropriate; but even so, they are operating a separate server that happens to coordinate with a running Austin REPL environment to get the necessary connect URL, etc. The "mounting" of a directory as the root of an Austin session's served content can and should be part of cemerick.austin
.