[Au2] Is anyone using router (not lite) in production?

Hi, after some initial doubts I’ve chosen au2 for a new project that started almost a year ago.
While the overall experience is surprisingly smooth (well, not that surprisingly after all, given how stable was au1), we’re worried about the router.
First of all, there are some major issues with load attribute - it basically doesn’t work even in the most basic scenario. I’ve filled the bug report, it’s been confirmed almost a year ago but is still not resolved.
Second, we’re experiencing some strange issues in the edge cases (very hard to reproduce) where the content of new route is rendered, but the old one is not removed yet - we end up having two views stacked together.

This makes me wonder whether anyone here uses the router (again, not lite) in the production?
Or is the router-lite a better way to go? We could probably plan switching the router if that is more stable; giving up a little of modularity for the stability of the solution

please advise :slight_smile:

I use the router-lite package for my routing needs as I don’t use any of the direct routing functionality or other features that come in the core @aurelia/router package. The @aurelia/router-lite router gets you functionality that is more akin to v1 routing or routing in other frameworks/libraries.

I can’t speak for the aforementioned issues, but I do know that the lite router is in good shape and there is a good chance you were probably not using direct routing anyways.

1 Like

I know of several projects that use the router successfully. As far as I know, the issues you’ve mentioned are resolved, but I’ll try and find some time this upcoming week to verify that.

1 Like

@dwaynecharrington thanks for the input on the router-lite. Will see how it goes with the router but either way it’s good to know there’s a safe plan B :slight_smile:

@jwx thank you, looking forward to it.
I’m afraid the duplicated content is still there, I’ve seen it myself one or two times in our app in the recent days, I’ll try to prioritize the investigation into it to provide you with a repro.
as for the other issue ( Router load attribute: broken when using id & parameters.bind · Issue #1902 · aurelia/aurelia · GitHub ) I’ve updated the repro code to use the beta 23 and the bug is still there.

You can check yourself here - Aurelia Recipes Completed (forked) - StackBlitz

1 Like

TL:DR :sweat_smile: Sorry @migajek no solution found yet, but a rather extended analysis of the route handling that caused the issue.

Curious to see what was happening, I’ve just started the StackBlitz environment.
I’ve opened the developer console, and one of the things mentioned is the loadloading deprecation/advise. It’s mentioned on each followed route.

Next step was to reproduce the error, indeed, simply by clicking one of the recipes. Error was triggered.

I’ve set a breakpoint on the error handling function (createUnresolvedinstructionsError, line 8171 atm) to see the stack.

On first break, like the error mentions, there is one route left to handle.

And for the stack at that time:

Checking the stack for possible issues, the location of the 100-iterations guard actually contains several TODO’s. @ devs, might be worth checking those?

Right. This initially broke on the error, so let’s see what we can figure out between a few of the do-while runs. :slight_smile:

Set a new breakpoint on the first line within the do-while loop, see previous screenshot for the actual line. Rerunning the application.
While rerunning, with this breakpoint in place, I noticed that the do-while was ended because this.matchedInstructions.length became 0 (as expected).

Now, let’s try the Beef Stroganoff (getting hungry :stuck_out_tongue: )

So first thing is to see what scope contains. No clue yet where to look… so just a screenshot.


Interesting part (little more to the bottom), is the routerInstruction. It’s not the same in one of the trees, but slightly different

So let’s see where the loop iteration ends and see what might be causing the issue.

  • local var matchedEndpoints starts with an empty array.
  • clearEndpoints is empty as well
  • hooked is empty array, so === false check fails.
  • Trying to step into the else-if actually kills the iframe! Bummer! (reproducable!) Let’s see if info can be retrieved.
  • Baking a tart this time. hooked is not true, and hooked !== this.matchedInstructions is false. So not going into the else if.
  • since this.matchedInstructions is [], the for loop is not run.
  • skipping and skippingWithMore are empty arrays too.
  • … leading to a quite explicit Todo: { // TODO: !!!!!! && !foundRoute.hasRemaining))
    foundRoute actually is undefined there, so might be “just” a cleanup issue?
  • the next part is actually run, because the route is unrestricted (according to data)
    image
  • the finalEndpoint() sets this.hasAllEndpoints to true, and handles some states
  • this.run() → this.entities is empty, this.running is set to true
  • this.hasAllEndpoints = true, so inside if. guardedUnload is undefined, so no promise.
  • Right, reaching the end of the first iteration. this.cancelled is false, no changedEndpoints
  • Another TODO here!
    TODO: Use a better solution here (by checking and waiting for relevant viewports
  • this.matchingInstructions is still empty, this.instructions is not. And ofc this.running still true.
  • clearEndpoints is an empty array, so no change to this.instructions.
  • And last line of the original do-while: changedEndpoints still not containing any data.
  • In the while check, the getInstructionsForScope(scope) still returns the original instruction.

Conclusion

Right, reaching a conclusion of this analysis :slight_smile:
No changes in next iterations - as expected. The instruction is still the same. Guard count ofc decreasing to 0 which in the end will trigger the error.

So, what is causing the actual issue? Some possible culprits:

  • this.processedInstructions still empty
  • this.matchedInstructions still empty
  • since the setNextContent is within the matchedInstructions for-loop, I think this is where the check actually fails.
  • with one step earlier, the local const clearEndpoints might also be improperly set

Without deep knowledge it is a bit hard to exactly pinpoint, or to find a solution. But I hope this analysis helps a bit.

2 Likes

Thanks for letting me know and updating the repro! I’ll look into this as soon as possible and report back.

1 Like

This is helpful, thanks!

1 Like

O, btw, you might have noticed already, but I did not do an analysis about the actual calling code. So although I doubt it, it can still be a matter of misconfiguration or perhaps a little road instead of the happy path.

If that is case, the code does need to be made more monkey-proof. So either way changes needed :wink: Looking forward to your changes and opinion.

Second, we’re experiencing some strange issues in the edge cases (very hard to reproduce) where the content of new route is rendered, but the old one is not removed yet - we end up having two views stacked together.

I have seen this as well, but switched to the router-lite and haven’t seen it happen since.

2 Likes

The Aurelia 2 documentation references direct routing but I couldn’t find anything that defined what it is so I wasn’t sure what it meant other than implying that there was some form of indirect routing.

A deeper search came up with some unlinked documentation on routing that seems to define what it is:
(Direct Routing | aurelia-direct-router)

There is another mention in the source repository docs/user-docs/routing/direct-routing.md, but I don’t actually see this on the docs.aurelia.io site

Non lite router does seem half baked.

  • I second the content duplication.
  • Href without hashtags does not work well.
  • Navigation drops a default sub route when anchor is clicked
1 Like

Hi! I was refraining myself commenting here, as I am using router-lite in production and thus, my opinion on this topic might be very biased. Therefore, I rather wanted to hear the feedback of the community on this topic.

I just want to ask you guys, without wanting to hijack the main thread of discussion, are there any reasons that drive you away from the router-lite? Moreover, are there any scenarios, within the configured routing realm, that are poorly handled by router-lite?

Thank you!

To be honest, I don’t quite understand why it’s made complicated for beginners by offering two routers that, in my opinion, don’t have entirely happy names. In my opinion, the “Router lite” is a very comprehensive, reliable router that can do everything important apart from direct routing. The “Non lite” router, on the other hand, seems to be immature and offers no added value apart from direct routing. Bugs/issues also appear not to be fixed for a long time in the “non lite” router. Wouldn’t it make more sense, for example, to change the naming to:

  • configurable-router / default-router / .. (or similar)
  • experimental-direct-router

In my opinion, the aim should be to make it clear to beginners (for the time being) that the “router lite” is currently the better choice.

3 Likes

No reason except that “lite” is perceived as “with less functionality”. Heavy router should be removed imho

1 Like

@MaximBalaganskiy , thank you for the input. I’m happy it’s not only me having issues with the router.

@Sayan751 that is a very valid question, not a hijack at all :slight_smile:
To answer fully - the decision was made (by me) quite a long time ago, but as far as I remember it was something along those lines:

why would I pick the router-lite and possibly regret the limited functionality in the future, when there is no reason to care about the bundle size that much (already lots of heavy deps). Looks like a no-brainer, duh.

After over a year, there was not a single scenario where direct routing could even be considered. So the switch to router-lite is on the roadmap.

I agree with Maxim here - the lite in the name is somewhat repelling, apparently for no good reason actually.