vue-router: Lazy routes + SSR not working

I built off the HackerNews (Vue 2.0 SSR) example and modified the routes to be rendered out lazily:

src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const Foo = () => System.import('../views/Foo.vue')
const Bar = () => System.import('../views/Bar.vue')

export default new Router({
  mode: 'history',
  routes: [
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
  ]
})

When navigating directly to /, app loads fine. Clicking on the links to /foo as well as /bar works - the chunks for the respective routes are loaded in lazily as expected. But navigating directly to /foo or /bar to trigger a server render crashes the app with “module 0.server-bundle.js not found”.

I figured this might be my cue to prevent code splitting on the server, so I defined a constant via webpack in both client and server configs:

webpack.client.config.js

...
new webpack.DefinePlugin({
  BROWSER_BUILD: true
})
...

webpack.server.config.js

...
new webpack.DefinePlugin({
  BROWSER_BUILD: false
})
...

…Then modified the router file to look like this:

src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

// import Foo from '../views/Foo.vue'
// import Bar from '../views/Bar.vue'

const Foo = BROWSER_BUILD ? () => System.import('../views/Foo.vue') : require('../views/Foo.vue')

const Bar = BROWSER_BUILD ? () => System.import('../views/Bar.vue') : require('../views/Bar.vue')

export default new Router({
  mode: 'history',
  routes: [
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
  ]
})

This worked. Server renders rendered the right UI components depending on the route, and renders on the client fetched lazy chunks as intended.

However, upon closer inspection, it seems that this little trick causes the HTML rendered by the server to mismatch the VNode tree created by the client - which prevents efficient hydration on the client, instead re-rendering the entire app, which is less than ideal 😛

I’ve tried to get help on Gitter as well as on the forum (http://forum.vuejs.org/t/2-0-help-needed-with-server-rendered-lazy-routes/906) but those avenues didn’t get much attention.

Since this is trivial to do in React-land, I’m assuming this might be a bug.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 27 (22 by maintainers)

Most upvoted comments

Actually I found no other solution with Webpack 😞

I you find one I’d love to see it!

Hi @wuchang1123

Do you have this config? https://github.com/Atinux/vue-hackernews-2.0-lazy/commit/01094366ccbd1075426dad2a8b6b401ea6748344

If so, the c.0.js and c.1.js should not have any embedded CSS.