Closed damz closed 5 years ago
Nice, thanks for sending this! Hoping I'll have time to review this soon (midnight here, and quite busy in general at work).
One thing that immediately pops out to me: I think instead of using github.com/gopherjs/gopherwasm/js
we should probably use build tags instead to avoid breaking existing GopherJS users and at the same time support WASM users.
@slimsag That's is unfortunately not going to help, given that the code base already references "github.com/gopherjs/gopherjs/js".Object
explicitly.
(Note that gopherjs test
is currently broken in Travis CI because of gopherjs/gopherjs#865.)
@damz I am aware that Node
returns a js.Object
explicitly. My point is that with build tags, that could remain the case for GopherJS and not the case for wasm.
My point is that with build tags, that could remain the case for GopherJS and not the case for wasm.
That would mean the vecty API is different for GopherJS and Wasm, so users would need to change their code (how they use vecty) depending on whether they want to compile with GopherJS or Wasm. That wouldn't be great.
It works best when when the package API is pure Go, and github.com/gopherjs/gopherjs/js
, syscall/js
packages are not a part of that API surface. That way, it's an implementation difference that stays completely internal to your package.
I don't know if it's viable to achieve that with vecty, but I just wanted to share these observations. In the case of honnef.co/go/js/dom
, we could only do it by changing its API.
@dmitshur Agreed, even examples/todomvc
inside the repository relies on HTML.Node()
. This probably wants to become an interface somehow, but note that the "github.com/gopherjs/gopherjs/js".Object
have additional magic (notably the struct tagging) that the new "syscall/js".Value
do not have.
FWIW, I uploaded a demo of the Markdown example compiled to WebAssembly.
That would mean the vecty API is different for GopherJS and Wasm, so users would need to change their code (how they use vecty) depending on whether they want to compile with GopherJS or Wasm. That wouldn't be great.
@dmitshur I am aware this would be the case. I am approaching this with the assumption that mid to long term, everyone will be switching over to Go's native WebAssembly support and away from GopherJS, but I suppose that could be an invalid assumption on my part.
One fact that will likely always be true is that Vecty must expose some sort of access to the underlying DOM nodes, i.e. our public API will always have some way to get a js.Object
.
If my assumption is right and GopherJS will eventually go away, I think exposing something like gopherwasm
through our API makes Vecty less pure in the sense that it will try to support both GopherJS and WebAssembly. In this situation, I would rather offer what I consider to be a more clean API without using gopherwasm
.
If my assumption is wrong and GopherJS will stay around e.g. even once Go 2 comes out, I think exposing gopherwasm
would be the right choice (or, GopherJS should eventually just hook the syscall/js
package and Vecty could expose that, kind of like how net/http
works in GopherJS).
So I think the deciding answer for me boils down to the question: What is the future of GopherJS vs. WebAssembly?
As somebody that was intrigued by GopherJS, I never actually wanted to use it. With WebAssembly, I'm all over it. There are obviously differences in the details that I'm sure GopherJS people might prefer it, but from my point of view as a GopherJS outsider, with WebAssembly there is no reason for GopherJS. In fact, it's possible with some of the work we've been doing on top of the WebAssembly port, Vecty will become more popular focusing on WebAssembly.
@dmitshur @damz any thoughts / opinions here given my last message? (I am aiming to land WebAssembly support over the weekend, if possible, due to high demand for it in general)
@slimsag you might like to consider waiting for https://go-review.googlesource.com/c/go/+/142004 to land first?
@myitcv thanks for the link. Yeah, I agree, given that is likely to change our implementation significantly. It also seems others here haven't quite had a chance to give input on my last message (or they don't wish to); I'll wait a bit longer for now.
I am still currently leaning towards "GopherJS will one day go away (so we should expose a pure non-gopherjswasm
API)"
To answer your call for responses. I would prefer ecty to run inside wasm. In effect allowing me to output html directly over post message to the window thread. I don't want vecty running in gopherjs. This gets things much faster and make the window a single plain of html with a little bit of js for any interactivity.
The conceptual model relies on accepting a wasm web worker being a Server, and the window being the client. The wasm worker is doing everything and streaming out html through the post message ! Now the multi threading is formalised in that the window has its own thread. I know that the wasm and golang wasm have some significant architecture problems but that's another problem outside of vecty.
The question as to if gopherjs can be used in the window should be addressed. I am finding it useful for small interactive things like gathering form data etc or special UX effects.
It's been a while (too long) and I think the correct decision is likely to be supporting WebAssembly and GopherJS under separate build tags for the reasons outlined in my prior comment. I will work on adding support for WebAssembly using this approach.
Also, I don't know for certain yet, but I suspect my prior statement to be more true given recent discussion around sunsetting GopherJS here: https://github.com/gopherjs/gopherjs/issues/855#issuecomment-451750737
Some of this sparks questions for me about whether or not Vecty should live under the GopherJS organization long-term, file https://github.com/gopherjs/vecty/issues/230 for discussing that.
I've sent https://github.com/gopherjs/vecty/pull/232 which will supersede this PR by implementing the alternative approach I mentioned in my comments above.
This is a fully working implementation of WebAssembly support in Vecty.
The really nice thing here is that a given code base can be compiled to JavaScript or to WebAssembly with barely any change (the only thing absolutely necessary is to add a
select {}
at the end ofmain
for the WebAssembly version).But there are a number of obvious problems for discussion:
github.com/gopherjs/gopherjs/js
withgithub.com/gopherjs/gopherwasm/js
, and as a consequence introduces a large BC break;syscall/js
andgithub.com/gopherjs/gopherwasm/js
) does not have a way to call aCallback
synchronously, which the test suite hacks around by sleeping for 10ms (runtime.Gosched()
is not enough);github.com/gopherjs/gopherwasm/js
doesn't have the minimum support for native (i.e. non-gopherjs and non-wasm) builds, so the test suite fails undergo test
(but it passes under bothGOOS=js GOARCH=wasm go test
and undergopherjs test
).