go-app icon indicating copy to clipboard operation
go-app copied to clipboard

Make go-app compatible with GopherJS

Open nevkontakte opened this issue 1 year ago • 5 comments

...or, more precisely, not actively incompatible with GopherJS.

At a high level, this PR does two changes:

  • Use GOOS=js as a predicate for the client-side execution, instead of GOARCH=wasm. GopherJS builds the code with GOOS=js GOARCH=ecmascript, so with this change go-app will correctly detect which side is the client when compiled with GopherJS.
  • Factor out logic related to wasm-specific resources into a Driver, and allow users to provide an alternative implementation. It does not add any explicit support or mention of GopherJS, but it is now fairly trivial for the user to make it work with GopherJS.

The general idea here is that while go-app doesn't officially support GopherJS, the latter supports syscall/js package pretty well, so the only practical issue is that Go WebAssembly requires some special code to load and start up, whereas GopherJS-compiled scripts can be simply included via a <script> tag. This change effectively makes the wasm-specific part of the initialization optional, and also take care of not attempting to cache them in the service worker.

https://github.com/nevkontakte/go-app-on-gopherjs contains a Go Workspace, which demos use of go-app with GopherJS using this patch. The only caveat is that Go 1.18.x is required for GopherJS to work.

Fixes #819

nevkontakte avatar May 06 '23 21:05 nevkontakte

I can confirm that our current most important App is compiling without any problems when I use this branch through a 'go.work' directive.

oderwat avatar May 06 '23 22:05 oderwat

Sorry for the delay, I've been busy with other projects. I'll try to get to it this weekend.

nevkontakte avatar May 31 '23 20:05 nevkontakte

I for one hope this will get into the official code for two reasons,

  • this would allow us to migrate our web app step by step while go-app based code grow bigger and bigger in percentage until it finally takes over all then we can switch to wasm, but before that, I don't know any way for my go-app code to co-existing with our existing framework.
  • Seems to me that there is no hope for pre-compressed wasm in any near future (see #866), yet I still have a hope that gopherjs based solution can support pre-compressed. IE I don't mind at all my build time take a bit longer, as long as my server doesn't need to compress a 16M big file each time a request is made. Would that be possible @nevkontakte?

suntong avatar Aug 13 '23 21:08 suntong

@suntong you can call all your JS code from WASM, no need to GopherJS for that. The pre-compressed files problem IMHO is a GitHub pages problem and can't be solved by other vendors. You need to be able to send a Content-Encoding: gzip for pre-compressed data (and for loading % reporting the original length header). So you can do that with any "real" web server already. It just needs more fiddling at build time than having transparent compression running.

oderwat avatar Aug 13 '23 22:08 oderwat

@suntong you can call all your JS code from WASM, no need to GopherJS for that.

I thought so at first until I tried it with an example here. You can see @oderwat that in its test folder, the Javascript invoked fine from html page.

However, the same content, when rendered with go-app, the Javascript was not able to be invoked.

If you can make the example triggering JS code from WASM works, it'll be very appreciated. thx. If you indeed able to, please follow up at #859 instead.

The pre-compressed files problem IMHO is a GitHub pages problem and can't be solved by other vendors. You need to be able to send a Content-Encoding: gzip for pre-compressed data . .. It just needs more fiddling at build time than having transparent compression running.

Yep, quite agree.

suntong avatar Aug 14 '23 01:08 suntong