vecty icon indicating copy to clipboard operation
vecty copied to clipboard

Router implementation

Open pdf opened this issue 9 years ago • 24 comments

Hey, just did a quick first pass on a client-side router for Vecty, open to any feedback. I still need to work out what testing looks like under GopherJS, and will probably implement history API in addition to hash routing, but I think the base API should work.

https://github.com/pdf/vectyx/tree/master/router

pdf avatar Jan 26 '17 02:01 pdf

Thanks for filing this :) this is something I really want to look into soon.

emidoots avatar Jan 28 '17 01:01 emidoots

hi, I want to rerender the body when the store changes like the todomvc example does.


p := &components.PageView{}
store.Listeners.Add(p, func() {
	p.Items = store.Items
	vecty.Rerender(p)
})
vecty.RenderBody(p)

I tried

r := router.New(nil)
...
b := r.Body()
store.Listeners.Add(b, func() {
	vecty.Rerender(b)
})
vecty.RenderBody(b)

but I got the following error.

Uncaught Error: vecty: next child render must not equal previous child render (did the child Render illegally return a stored render variable?)
    at $callDeferred (client.js:1414)
    at $panic (client.js:1453)
    at Object.$packages.github.com/gopherjs/vecty.HTML.ptr.restoreHTML (dom.go:175)
    at Object.$packages.github.com/gopherjs/vecty.HTML.ptr.Restore (dom.go:216)
    at doRestore (dom.go:336)
    at Object.Rerender (dom.go:299)
    at $b (client.go:22)
    at Object.$packages.github.com/gopherjs/vecty/storeutil.ListenerRegistry.ptr.Fire (storeutil.go:31)
    at Object.Dispatch (store.go:63)
    at main (client.go:26)
    at $init (client.js:33575)
    at $goroutine (client.js:1473)
    at $schedule (client.js:1530)
    at $go (client.js:1506)
    at client.js:33586
    at client.js:33589

newlix avatar Feb 07 '17 15:02 newlix

You're running into #70 / #78. I'm not sure if I've tested the router without the patch I posted in #78.

pdf avatar Feb 07 '17 16:02 pdf

I made a repo to reproduce the bug. I haven't tested with your patch. https://github.com/newlix/todomvc

newlix avatar Feb 07 '17 17:02 newlix

You can fetch https://github.com/pdf/vecty/tree/reuse-components or cherry-pick 22146ed23190ea1aa42ca1a165492c00d3548db2 if you want to try the patch.

I can see why the router may trigger that panic if Rerender is called when the route hasn't changed, but I think the router logic is sound if #78 can be solved - I think I'd like to wait and see what happens there before making any dramatic changes.

pdf avatar Feb 07 '17 17:02 pdf

There's no need to duplicate work on the router. There is one that is already functioning at https://github.com/go-humble/router.

ghost avatar Mar 21 '17 23:03 ghost

/cc @albrow who created go-humble/router, FYI, your project was mentioned here.

dmitshur avatar Mar 22 '17 00:03 dmitshur

@xoviat this router supports nested routes, and rendering only the changed route component (provided #94 or similar is merged), plus url params - things that the humble router does not.

Experience with client-side routers in complex applications with large numbers of elements has informed me that rendering only the changed route component in particular is a worthwhile goal.

pdf avatar Mar 22 '17 00:03 pdf

@shurcooL thanks for the heads up. Firstly, I'm totally okay with having multiple GopherJS router implementations if that's the direction the community wants to go. Ultimately it's up to the Vecty maintainers to decide what makes the most sense for the project.

Just to clarify a few things about go-humble/router:

  • We recently added support for query parameters in version 0.5.
  • It supports nested routes, i.e. routes of the form "account/{account_id}/invoices/{invoice_id}".
  • It is view layer agnostic. I want to keep it this way, so that might be one reason it's not a good fit for you.
  • It automatically uses the Browser History API if it detects support for it, and otherwise it seamlessly falls back to fragments (e.g. the # part of a URL).

It might be worth looking into using go-humble/router as a starting point. It should be possible to hook into the callback and do whatever additional logic you want to do (e.g., re-rendering certain components). I also totally understand if you choose not to head in this direction.

Happy to answer any questions, and I'm eager to see what you decide. Vecty looks like a cool project!

albrow avatar Mar 29 '17 01:03 albrow

@albrow to clarify - when I mentioned nested routes, I meant hierarchical nesting - this router probably has more in common with react-router than mux-style http routers. I think this is a more natural fit on the client-side since you can map routes into the DOM for nested views, and this is what allows the router to determine which sub-trees are affected by a route change, and to re-render only those. The latter would be non-trivial to achieve using the callback method in go-humble/router, which is why I put this together.

This is pretty much just a PoC currently, which is why it's not in its own repo, however I may extend and publish with a couple of features it's missing if there's interest, or if some other strategy ends up being preferred here.

I posted here mostly to generate discussion, so I appreciate the input.

pdf avatar Mar 29 '17 02:03 pdf

@pdf Out of curiosity, do you know whether there is any meteor-equivalent library that exists?

ghost avatar Mar 29 '17 02:03 ghost

@xoviat I'm afraid I don't have any experience with meteor.

pdf avatar Mar 29 '17 02:03 pdf

No clue why I tagged this as long term, this seems important for 1.0.

emidoots avatar Oct 01 '17 08:10 emidoots

@slimsag I don't think I'd predicate a v1.0 release of Vecty on having a canonical router implementation. Even React doesn't include one as part of core - react-router was developed entirely independently.

pdf avatar Oct 01 '17 08:10 pdf

Respectfully, I disagree.

IMHO the React ecosystem is a mess because there are so many options and non-canonical ways to do things. This has led to the creation of projects like https://github.com/facebookincubator/create-react-app and a myriad of 'react starter kits'. Additionally the split between babel/webpack, npm/yarn, using redux or something else, etc.

There are so many choices in the React ecosystem that it's hard to start a project, especially as a beginner. I don't disagree that those choices should be offered, but there should always be one path that is deemed "official".

I feel this is similar to how Go encourages the use of the go tool rather than just using its compiler + linker and suggesting you choose between Makefiles, CMAKE, bash scripts, etc.

I think that if we do not have a batteries-included approach by 1.0, then we're not much better than React and it will be very hard to get the majority of (backend) Gophers being able to write some frontend code.

But in reality, the only difference in saying that v1.0 relies on a router, dispatcher, store, etc. is that:

  1. I will not publicize or encourage folks to write about Vecty on social media/blogs until then.
  2. I will not host documentation in a super-public area (for example, it'll be on a separate git branch).

That doesn't mean I will say "Vecty's core APIs are not stable until we get a router" though :P I think Vecty will be very useful, even for some daring production users, for quite some time before 1.0 is released.

emidoots avatar Oct 01 '17 08:10 emidoots

Those goals are certainly sensible, and I appreciate the clarification of definitions. My thinking was that it may be useful to be able to communicate the core as stable, without having to have all the value-adds solidified, though I suppose the development of them may inform some design changes, so the exercise may prove worthwhile any way.

pdf avatar Oct 01 '17 08:10 pdf

Yes, issues like #148 come to mind actually.

Currently, I view the arch-design tag as issues that may affect the core in some way (but obviously, some issues like this one I expect to affect it much less or perhaps not at all)

Once the core is stable, we can also communicate this in https://github.com/gopherjs/vecty#current-status by changing APIs will change to something like Core APIs will not change etc 😄

emidoots avatar Oct 01 '17 08:10 emidoots

Just throwing this out there, but one idea could be to wrap a javascript router with a shim for 1.0 and then possibly reimplement it later in Go. It seems that re-using react router would save a significant amount of software design and it might get Vecty out the door sooner.

ghost avatar Oct 01 '17 18:10 ghost

@xoviat that doesn't really work, I'm afraid. A router implementation is not that much work anyway.

pdf avatar Oct 01 '17 21:10 pdf

I was wondering, what is the state of this? I would love to use vecty on a big personal project instead of vuejs, and component routing is crucial .

gernest avatar Feb 03 '18 07:02 gernest

Neither @slimsag nor I have had any real time to dedicate to Vecty over the past couple of months I'm afraid @gernest.

pdf avatar Feb 03 '18 07:02 pdf

What's going on with this great enhancement? Any update on this?

AnikHasibul avatar Sep 09 '18 21:09 AnikHasibul

has anyone tried this? https://github.com/marwan-at-work/vecty-router

pyrossh avatar Jul 22 '19 15:07 pyrossh

has anyone tried this? https://github.com/marwan-at-work/vecty-router

I do, it works quite a bit.

EDIT: to follow up on this, I just had to apply a small fix about routes duplications (https://github.com/tbruyelle/vecty-router/commit/27b1d572f0b0f2f260ac95cf1f95acf3d22ad86f), and added support for go modules and syscall/js (https://github.com/tbruyelle/vecty-router/commit/7d7405a23a3a9f7503bb4a308a064e0342173261)

tbruyelle avatar Jul 22 '19 15:07 tbruyelle