-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support a React/next.js-like framework #80
Comments
I am curious of how you are gonna do this, will you do this with mirror functions or just through functions that allows you to access javascript functions/variables? |
Hmm, not 100% sure what you mean by mirror functions. Do you mind sharing an example? I keep oscillating between having more of a Go way of doing things and a React way of doing things. The farther I go towards React, the more familiar the API is, but the more Go AST rewriting I need to get Go there. I think a pure Go implementation will require rethinking how React works. @tj has experimented with how this would look a bit. The parts I'm struggling the most with are the lifecycle hooks and the local state. Knowing if they're really needed or if there are other ways to do the same thing. I think for the first release, I'd think like to make it as compatible with the existing frameworks as I can, and will take advantage of the fact that the actual data flows once compiled are in JS and untyped. We'll leave it up to the frameworks (React + Preact) to give values back that are consistent with the types in our structs. This is what I have in mind for right now for the API: package basic
import "time"
////
// React stuff (incomplete)
////
// Component interface
type Component interface {
SetState(state interface{})
}
// Node interface
type Node interface {
String() string
}
// Text fn
type Text string
func (t Text) String() string {
return string(t)
}
////
// Clock component
////
// Props struct
type Props struct {
Name string // property
}
type state struct {
Count int
}
// Clock struct
type Clock struct {
Component
props Props
state state
}
// DidMount fn
func (c *Clock) DidMount() {
go func() {
time.Sleep(1 * time.Second)
c.SetState(&state{
Count: c.state.Count + 1,
})
}()
}
func (c *Clock) WillReceiveProps(nextProps Props, nextState state) {
}
// Render fn
func (c *Clock) Render() Node {
return Text(c.state.Count)
} PROS
CONS
This is still very experimental though. I'm really hoping you guys have some ideas here too! |
@matthewmueller Actually this looks very neat and immediately familiar for everyone who already worked with React. But there is a few thoughts i had when thinking about how this all plays along Go's existing technologies. So sorry to be the odd guy, but i thought about an interesting way to use joy in regards to how we use go today to deliver websites. The main goal is to use Go's server-side web prowess to have a fast first render and the isomorphic nature to have just one Data Type and it's methods to serve both the needs of server and client side. It uses existing Go technology like the template package. For Illustration how this might look like i made up some dummy design suggestion. So let's take a look at a very minimal Go server side example. it's not actual code like the Component interface and WebComponent Data type is stuff that should be realized in a library that powers the whole thing.
Then we can hook functions into the template parser to inject our javascript side of the we component to take over once go has done the first loading of the component via standard html/template.
In a nutshell the beauty lies in tapping into existing Go Web techniques for a blazing first render. There is a lot of open questions like synthetic Events, Two-Way Databinding, yes or no, Shadow DOM (i think it's a bit hyped and not a must have). Efficient rerendering techniques and so on. Once again sorry for slightly side tracking this topic, but at this early stage i thought it would be interesting to take a look on where the journey could go and to make sure to not idiomatically think too slavishly alongside existing js solutions but to harness the full power of go with its beautiful design principles. Before i forget, this way you also have perfect editor support for html css and js. Let me know what you think. |
Thanks for your thoughts on this! I'll need to review a bit more, but this is definitely the kinds of things I'd like to see and try. I think this is more closer to what Vue does, but able to take advantage of all of Go's existing tooling, which is rad. I was thinking Vue would actually probably be better final target, but given the plethora of tooling already available in Go, I think it makes more sense to start with a Next.js-like framework and just have all the code be Go. I think your approach, once refined, would build towards a longer-term goal which is to have the react-like framework written in Go and using more of Go's idioms. I'm hesitant to start on this work at this stage because React is so battle-hardened, but I'm hopeful there will be others that take on this challenge. |
Yeah i agree getting something out now is better than trying to rethink reactive framework from a go perspective right from the start. Having something workable shorter term will ignite the sparks anyways. About the limitations you mentioned:
As long as the architecture is built with these things in mind and a logical place is reserved where missing features can be implemented in future iterations you should be good.
All the things you get for free from Go will make up for slightly less convenience than usual. I wouldn't sacrifice proper distinction between props and other fields by abusing the Capitaliztion for a different paradigm.
Since joy doesn't work like gopherjs and will probably have very slim libraries in the near future, DCE can be worked on when it actually becomes a topic. On a sidenote i read like 3 articles covering joy in my google news site, so gratz on that :-) |
For those interested, I'm writing down a spec of how this is going to look: https://docs.google.com/document/d/12KWk9wnQMyy8fnOu7UV8eJorGHcUN710aIYJF2ppJRE/edit?usp=sharing It's very much a WIP and I would love some help carving it into shape. I'm finding it's a lot easier to think through the design separately from the implementation. If you have time, read through and add comments 😊 Happy holidays! 🎄 Update: I linked to a private project called elmo in there, if you'd like to take a look at that, let me know and I'll invite you. |
Preact is well structured and small with only a handful of short Typescript files which makes it the best candidate for porting/adapting. Wise choice. The only downside is that it is kind of the second slowest react clone, but this should be a non issue for the scope of this first iteration.
One thing that people might want to make a "dumb" component for might be repetitive large strings, like inline svg e.g close button etc.
The question is, will doing it like this make things WAY easier for you or not. If it does, don't worry since non enthusiast Developers who just want to be productive here and now are bound to hate the first iteration. It's the enthusiasts who see the potential in it and will help you to make this thing being production ready later on who count. If you think it won't make a big difference for you doing it the HTML way i'd bet on devs loving their documentation bits of their UI Framework of choice working without too much hassle.
If you wish to be able to use something like URI parsing and manipulation (maybe abusing the fragment part for interesting things) https://medialize.github.io/URI.js/ might be interesting to you. I tried it out on a project where i had to work with documents loaded from a server editing them, renaming etc. and it worked like a charm. https://github.com/medialize/URI.js/blob/gh-pages/src/URI.min.js is 46kb minified , so probably only 7kb or so gzipped.
Only for the root components if i got that right from next.js documentation. Other only remotely related problem is: Since we don't have constructors in go we need to offload that part to one of the lifecycle hooks.
and not run into a situation where you have too much code that does two different things in 1 hook.
Asked the other way around would having a generic implementation that only makes sure that all of the pieces of data needed are structured and accessible for jolly -export=netlify, export=whatever not be more desirable? Reading up on the different formats and the ingredients of the recipes should give you an idea what data needs to be aggregated and you can delegate that to a different task enabling you to focus more on the general goals. Adding Command Line Flags later on to transform generic data would not cause any portability issues, but baking in some sort of default export format might. |
Thanks for taking the time to read though this!
Great point, I think there should be something where you can just write raw HTML. It just gets a bit tricky when templating starts to get involved. I've definitely run into your exact example before though, bringing in SVGs. You wouldn't want to convert those by hand, though it's worth noting that you still need to do some conversion with react, changing hyphen case to camel case. I think we wouldn't even need to do this though.
I'm sort of betting that having the type system and syntax highlighting will make this worth it, but I'm not 100% sure and I'm open to alternative solutions here. This could also be solved at the editor level too with pre-compiling HTML into these functional elements.
Ahh yep, I've used that one. Filling in the possibility space a bit, I was also looking at https://github.com/component/url, though this doesn't actually work in web workers, so that might be an issue. There's also this one: https://github.com/unshiftio/url-parse. There's also a browser native version now, but I'm not sure about browser compatibility.
Good question, the more I think about this, the more I think you're right on. No reason to conflate the hooks for a few less keystrokes.
Oh yah, that could work too. Eventually, it'd probably be good to have a This is mostly an issue of... do we have the ability to do this via API calls on AWS? |
that would do the job.
That's true. With all the parsers and tokenizers around now for go shouldn't be hard to get some intermediate representation going for syntactical sugar later on.
Haven't heard of that one, but i know there is some nice hack by creating an anchor dom element and abuse it for parsing it's href. An Example that looks a bit more robust is here: https://j11y.io/javascript/parsing-urls-with-the-dom/
TBH i don't know enough about this stuff. I am blessed with an abundance of dedicated servers for my work :-) |
Hey folks! Now that I've managed to get the installation process under control, I'm starting to focus on getting a really minimal, but productive frontend framework working that either uses or is based on React/Preact & next.js/Vue.
This has been more difficult than I thought because some of React's paradigms don't really translate 1:1 to Go. Specifically how they do setState and some of the lifecycle methods like
componentWillReceiveProps
are tough to model in the same way.I'll be filling in this issue with more information and thoughts as I go, but I'm also looking for ideas. We have tons of variables we can tweak, so it's just about figuring out what feels right. For example, some of the options we have are: tweaking React's API a bit to more like idiomatic Go, generating additional Go code via
go generate
, updating Joy's JS output to better support React.Please help make Go great for web development!
The text was updated successfully, but these errors were encountered: