Skip to content

Vue router resolves async route component before global guard hook has been resolved #1329

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

Closed
sqal opened this issue Apr 12, 2017 · 3 comments

Comments

@sqal
Copy link

sqal commented Apr 12, 2017

Version

2.4.0

Reproduction link

2.4.1 - https://jsfiddle.net/bfpuee6e/
2.3.1 - https://jsfiddle.net/0ogdn5mu/

Steps to reproduce

  1. Open reproduction link for 2.4.0 and check console logs, you can see that vue router resolves async component even though next() callback in global beforeEach hook hasn't been called
  2. Open reproduction link for 2.3.1, this time there's no 'resolve fn called' log

What is expected?

i expect the same behavior in 2.4.0 as in 2.3.1.

What is actually happening?

Vue router now resolves async component before global hooks have been resolved.

@posva
Copy link
Member

posva commented Apr 13, 2017

I'm not sure if we should go back to the previous behaviour because we can start getting the async comp while the beforeEnter is doing some computation or fetching and therefore provide a smoother experience.

I updated your repro to this: https://jsfiddle.net/qs161n6g/1 which is clearer in my opinion

@sqal
Copy link
Author

sqal commented Apr 13, 2017

because we can start getting the async comp while the beforeEnter is doing some computation or fetching and therefore provide a smoother experience.

I see but let me explain (based on my app auth-flow) why I would like to prevent this behavior... imagine this scenario:

I have these routes:

{
  path: '/',
  beforeEnter(to, from, next) {
    next(isUserLoggedIn ? true : '/login')
  },
  component: () => import('./views/Panel')
  children: [
    {
      path: '',
      component: () => import('./views/Panel/Home')
    }
  ]
},
{
  path: '/login',
  beforeEnter(to, from, next) {
    next(isUserLoggedIn ? '/' : true)
  },
  component: () => import('./views/Login')
}

and some relevant parts on my app:

// don't resolve initial route due to pending authentication
router.beforeEach((to, from, next) => {);

// later in the code
AuthService.checkAuth().then((loggedIn) => {
  // remove global hook
  router.beforeHooks = []

  // redirect user based on loggedIn status
})

How things worked before:

  1. User enters the site http://mysite.com/
  2. Browser waits with fetching initial route chunk
  3. When authentication is resolved I redirect user to '/' or '/login' and then async component is fetched

How things work now:

  1. User enters the site http://mysite.com/
  2. AuthService is doing its thing, but both components Panel and Home are fetched by the browser immediately

And this is a problem for me because, both chunks (Panel/Home) are very huge in my case ~350 kb, and and therefore I would prefer not to preload them before my authentication check is complete.

So my question now is - is there a way to bring back the old behavior or some kinda workaround for my case? I hope all is clear to you and appreciate the help :)

@posva
Copy link
Member

posva commented Apr 13, 2017

I see. There's probably something that can be done to improve the control of when to fetch the async view

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants