GopherJS – A compiler from Go to JavaScript
github.com
github.com
http://en.wikipedia.org/wiki/Gopher_(protocol)
Time to pour one out for protocols loved and lost...
https://gopherjs.github.com/playground/ - GopherJS Playground.
(It compiles Go code to JavaScript in your browser using the GopherJS compiler itself compiled to JavaScript. There is no backend being used.)
https://godoc.org/honnef.co/go/js/dom - DOM bindings.
https://godoc.org/honnef.co/go/js/xhr - XHR bindings.
- Making my Markdown Format package for Atom have zero external dependencies by compiling the Go code into JavaScript. That way there's no need to install and point to the markdownfmt binary, making install easier. https://github.com/shurcooL/atom-markdown-format/commit/6b5f...
- Replacing JavaScript with Go code in Go Package Store, still a WIP PR because I need to figure out a `go get` difficulty, but aside from that it works perfectly well. https://github.com/shurcooL/Go-Package-Store/pull/18
- Various experimental things that run in the browser and perform operations that use existing Go code. For example: https://dl.dropboxusercontent.com/u/8554242/dmitri/projects/... https://dl.dropboxusercontent.com/u/8554242/dmitri/projects/...
- At work, I've created a small standalone project with a frontend UI that reused some common structs and html template code between the frontend and backend (ala node.js, except all in Go).
- Working on porting my small OpenGL game written in Go to run in the browser. The goal is to have the same Go code use OpenGL when on desktop, but use GopherJS and WebGL when compiling for the browser.
Basically, it lets me do all the things that one would normally be forced to use JavaScript for (i.e., frontend code) but without having to use JavaScript (I'm not good at it and I don't like it), while benefitting from Go compiler to catch errors, autocomplete, godocs, goimports, etc. It also allows me to import and use existing Go packages that perform non-trivial tasks.
https://github.com/azul3d/issues/issues/29 - Very relevant discussion with good resources/links/info.
https://github.com/ajhager/engi - 2D game library for Go with desktop/browser/android targets.
https://github.com/shurcooL/play/tree/master/57 - Simple WebGL/GopherJS render triangle demo.
https://github.com/shurcooL/play/tree/master/58 - Unfinished attempt to make the above compiled to two desktop/browser targets.
its like clojure core.async only more powerful.
Can you explain why its more powerful than core.async?
The library: https://github.com/ubolonton/js-csp
Also, I meant clojurescript core.async, not clojure.
GopherJS happily compiles itself, however. The raw source code looks to be about 250KB. The native binary ends up 7.7MB, and the unminified js is 3MB. A pass through UglifyJS with default options reduces that to 1.7MB (I have not tested the result):
~/gocode/bin$ ls -lh *gopher*
-rwxr-xr-x 1 nknight staff 7.7M Oct 14 14:02 gopherjs
-rw-r--r-- 1 nknight staff 3.0M Oct 14 14:32 gopherjs.js
-rw-r--r-- 1 nknight staff 233K Oct 14 14:32 gopherjs.js.map
-rw-r--r-- 1 nknight staff 1.7M Oct 14 14:41 min-gopherjs.js
~/gocode/bin$
Edit: Oh, and the playground example minifies to 300KB: ~/gjstest/playground$ ls -lh
total 1784
-rw-r--r-- 1 nknight staff 194B Oct 14 14:05 main.go
-rw-r--r-- 1 nknight staff 536K Oct 14 14:53 main.js
-rw-r--r-- 1 nknight staff 42K Oct 14 14:53 main.js.map
-rw-r--r-- 1 nknight staff 300K Oct 14 14:54 min-main.js
~/gjstest/playground$That part is constant. Once you write more code, the generated output will grow very gracefully as expected.
The output is quite large (order of 1~2 MB), even when minified, so it might not work well yet for user facing sites with huge traffic. That could be an ongoing improvement effort for GopherJS to benefit from. However, for smaller sites or offline utilities it works absolutely great.
This may not matter on desktop intranets, but it will matter on the mobile web.
Edit: I want to expand on this a bit. I'm curious about how the workflow is now and what's envisioned. Things like the above mentioned and also LightTables insta-repl make for great workflow value propositions. I very much like Clojure, but I like Go as well and have written much, much more of it. So this is very interesting, but.. Do I need to write the Go code blind, then compile to js, then refresh and test my page to see what's going on?
Still plenty of room for improvement, but there are people who are excited about making GopherJS fun to work with.
http.Handle("/assets/script.go.js", gopherjs_http.GoFiles("./assets/script.go"))
Then my html files (or templates that generate html via html/template package) include it with: <script src="./assets/script.go.js" type="text/javascript"></script>.
That way, I can edit the ./assets/script.go file in my code editor (with goimports on save, autocomplete, etc.) with the server running. Whenever I refresh the page in the browser, new compiled JavaScript is loaded.It's really nice to be able edit the Go script, css, html template and not need to restart the web server for effects to take place. Just refresh the page, and see new code running.
That's my workflow so far.
I have plans to improve that code so that it accesses the assets via a virtual file system interface, so that it's possible to have a debug version that hot-reloads all files from disk, and a release version that embeds the assets into the Go binary so it can run anywhere.
Part of me fears the output though. It can be rather verbose, large, and is quite abstract from the original code. Debugging and code-size worry me greatly.
FWIW, I've done some crazy things and so far I've seen that things work surprisingly fast. Performance has not been a bottleneck yet.