You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to suggest a few improvements to HMR.
I observe updateRoutes is only invoked when adding or removing page.
In updatePage there's a comment:
// no need to manually trigger the update of vue-router/auto-routes because// the change of the vue file will trigger HMR
That's not accurate.
Vite will notice the module has changed and invalidate it, but it will not actively push it through HMR to clients.
As auto-routes is typically not referenced by pages or components, only by the module that create routes, it might not be reloaded for a long time, if ever.
It also looks that this "late update" is not considered HMR and just creates duplicate modules in the front-end, which led me to all sorts of confusing issues. I would suggest to trigger HMR when the routes are modified
Is this really the right place to do it though?
Consider:
extendRoutes and beforeWriteFiles can do a lot of shenanigans that may have different dependencies and are basically impossible to predict.
Updates trigger basically on every page edit. That's often , and most of the time no route-impacting change is actually made.
For these reasons I would suggest a different approach altogether: after the auto-routes virtual file has been rebuilt, compute a hash. If the hash is different from previous generation, send HMR. This covers all possible changes (add/remove/update/extensibility changes) and never sends unnecessary HMR to front-end.
Tip
Some tips for people googling how to update more than the router itself: auto-route exports handleHotUpdate(router), which you can use to register your app router. With this, your router will automatically be updated whenever auto-routes is HMR. Very cool!
If you want to update more than the router, for example if your navigation menu is built off of your route table... it's possible but not obvious.
Because auto-routes self-accepts HMR, it won't propagate further: don't try to accept it with hot.accept("/__vue-router/auto-route").
The way to go is to subscribe to notifications with import.meta.hot.on('vite:afterUpdate', args =>...) and filter args.updates.some(u => u.acceptedPath === '/__vue-router/auto-routes')
Note that you will not find the new module in args and the self-accepting HMR does not update the existing exports, only the router.
So to get the updated routes, your only way is to get your router and call router.getRoutes().
@posvaMaybe this process is worth simplifying?
The obvious idea (to me) is a custom message hot.on('auto-routes:afterUpdate', routes => ..) but the bummer is that these messages can only be sent by server.
Alternatively auto-routes could export a onRouteUpdated(routes => ..) function to register listeners that are called by accept?
The text was updated successfully, but these errors were encountered:
The process is definitely worth simplifying, maybe even fixed. Without the current implementation, there was no invalidation at all and things were even worse...
The info you provided here is really helpful, thank you. I will definitely take a look
I would like to suggest a few improvements to HMR.
I observe
updateRoutes
is only invoked when adding or removing page.In
updatePage
there's a comment:That's not accurate.
Vite will notice the module has changed and invalidate it, but it will not actively push it through HMR to clients.
As
auto-routes
is typically not referenced by pages or components, only by the module that create routes, it might not be reloaded for a long time, if ever.It also looks that this "late update" is not considered HMR and just creates duplicate modules in the front-end, which led me to all sorts of confusing issues.
I would suggest to trigger HMR when the routes are modified
Is this really the right place to do it though?
Consider:
extendRoutes
andbeforeWriteFiles
can do a lot of shenanigans that may have different dependencies and are basically impossible to predict.For these reasons I would suggest a different approach altogether: after the
auto-routes
virtual file has been rebuilt, compute a hash. If the hash is different from previous generation, send HMR. This covers all possible changes (add/remove/update/extensibility changes) and never sends unnecessary HMR to front-end.Tip
Some tips for people googling how to update more than the router itself:
auto-route
exportshandleHotUpdate(router)
, which you can use to register your app router. With this, your router will automatically be updated whenever auto-routes is HMR. Very cool!If you want to update more than the router, for example if your navigation menu is built off of your route table... it's possible but not obvious.
Because
auto-routes
self-accepts HMR, it won't propagate further: don't try to accept it withhot.accept("/__vue-router/auto-route")
.The way to go is to subscribe to notifications with
import.meta.hot.on('vite:afterUpdate', args =>...)
and filterargs.updates.some(u => u.acceptedPath === '/__vue-router/auto-routes')
Note that you will not find the new module in
args
and the self-accepting HMR does not update the existing exports, only the router.So to get the updated routes, your only way is to get your
router
and callrouter.getRoutes()
.@posva Maybe this process is worth simplifying?
The obvious idea (to me) is a custom message
hot.on('auto-routes:afterUpdate', routes => ..)
but the bummer is that these messages can only be sent by server.Alternatively
auto-routes
could export aonRouteUpdated(routes => ..)
function to register listeners that are called byaccept
?The text was updated successfully, but these errors were encountered: