The only example I can think of currently is hot package swapping (aka HMR). But I bet more tooling can really benefit if we exposed the $packages variable globally.
Of course, this should only be done for development purposes and not production.
Currently, I built an experimental HMR that required exposing $packages globally so that you can compile multiple programs (or the same program multiple times) and be able to update only one package while the rest of the program is still running and can immediately read and execute the updated code.
In order to achieve this, the GopherJS compiler needs to expose $packages as well as some (if not all) of the closures. This is because the compiler does closure comparisons.
Here's how I initially made it work: https://github.com/marwan-at-work/gopherjs/commit/8a708119da3d2176aa1208397f463cb056e9ebee
Of course, this is just hacked together and would need to sit behind a -expose flag or something. Would love some pointers to maybe do it more efficiently than just exposing everything. One thought I have is to put all of the closures inside one object so that we don't pollute the $global scope.
Here's a working experiment of the hot package swapper: https://github.com/marwan-at-work/hmr
Happy to hear any thoughts for/against any of the above :)
Thanks for open-sourcing https://github.com/marwan-at-work/hmr btw @marwan-at-work !
Unfortunately I won't have time to look at any of this for at least ~1 month, but I wanted to ask: how hard would it be to integrate this directly into gopherjs serve?
For me that sounds like the logical starting point to mainstreaming this feature, and then later figuring out how other (non-gopherjs served) applications could run with HMR would be the secondary step (there is some existing work in this area to reuse pieces of the GopherJS build system, such as https://github.com/shurcooL/gopherjslib), which could be a good starting point.
(P.S. Marwan posted a cool demo video of this in the #vecty channel, https://gophers.slack.com/files/U4YLUBRHU/F89MMMKFY/hmr.mov)
@slimsag no problem! it's super early and does not cover all edge cases, so you have time 馃槃
Including HMR in gopherjs serve should be doable once we have the compiler supporting the two requirements: 1. global scope (this issue) and 2. building non-main packages and/or optionally disabling dead code elimination: https://github.com/gopherjs/gopherjs/issues/723
gopherjslib sounds helpful for sure, but it seems to use the gopherjs compiler directly, so issue#723 is still valid in that we'd need to be able to compile a non-main package (and/or have a flag to disable DCE)
@marwan-at-work I have a question related to this.
Have you thought about or considered making this functionality exposed via the plugin package interface? If so, what were those thoughts?
@shurcooL Yes I have! Regardless of HMR, making plugin work for GopherJS would be a total win :)
As for HMR, I don't think the plugin feature would be a smooth developer experience. This is because every single vecty.Component you create must now be in a main package and must be initialized through the plugin.Open and converted from an interface{} to MyComponentStruct{} in the parent's Render method.
Unless there's a way to do the plugin logic once in your code base? Not sure how.
Most helpful comment
@slimsag no problem! it's super early and does not cover all edge cases, so you have time 馃槃
Including HMR in
gopherjs serveshould be doable once we have the compiler supporting the two requirements: 1. global scope (this issue) and 2. building non-main packages and/or optionally disabling dead code elimination: https://github.com/gopherjs/gopherjs/issues/723gopherjslibsounds helpful for sure, but it seems to use thegopherjscompiler directly, so issue#723 is still valid in that we'd need to be able to compile a non-main package (and/or have a flag to disable DCE)