3

I have a vue 3 app with vue-router and vuex installed which is working very well. Now I'm trying to integrate server side rendering for it. This was also working very well until I integrated defineAsyncComponent() to lazy load my routes.

As soon as I switch from this router implementation:

import {defineAsyncComponent} from "vue"
import {createRouter} from 'vue-router'
import Home from '../pages/Home.vue' //<-- no async import

export default function (history) {
    return createRouter({
        history: history,
        routes: [
            {
                path: '/',
                component: Home
            },
        ]
    });
}

to a variant with async components:

import {defineAsyncComponent} from "vue"
import {createRouter} from 'vue-router'

const Home = defineAsyncComponent(() => import('../pages/Home.vue')); //<-- changed to a async import

export default function (history) {
    return createRouter({
        history: history,
        routes: [
            {
                path: '/',
                component: Home
            },
        ]
    });
}

I get tho following error when I try to render the app on server side (client side is still working well and async components are loaded as expected):

/var/app/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1542 return (comp.__props = shared.EMPTY_ARR); ^ TypeError: Cannot add property __props, object is not extensible at normalizePropsOptions (/var/app/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1542:30) at createComponentInstance (/var/app/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5934:23) at renderComponentVNode (/var/app/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:159:22) at renderVNode (/var/app/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:244:22) at renderComponentSubTree (/var/app/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:213:13) at /var/app/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:174:29 at async unrollBuffer (/var/app/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:355:24) at async unrollBuffer (/var/app/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:361:24)

This is the vite config I use to build everything:

const {ssrBuild, build} = require('vite')

;(async () => {
    await build({
        mode: 'development',
        assetsDir: '.',
        emitAssets: false,
        rollupInputOptions: {
            input: './resources/js/entry-client.js'
        },
        rollupOutputOptions: {
            entryFileNames: '[name].js'
        },
        outDir: 'public/build/client',
    })

    await ssrBuild({
        mode: 'development',
        rollupInputOptions: {
            inlineDynamicImports: true,
            input: './resources/js/entry-server.js'
        },
        outDir: 'public/build/server',
    })

    process.exit();
})()

and this is my server-entry.js:

import renderer from '@vue/server-renderer';
import createApp from './main.js';

const {app, router, store} = createApp(context, true);

router.push(context.url);

router.isReady().then(() => {
    renderer.renderToString(app).then((html) => {

        var data = JSON.stringify({
            'resourceHints': '',
            'styles': '',
            'html': html,
            'state': store.state,
            'scripts': "",
            'preload': '',
        })

        console.log(data);
    });
});

Do you have any idea why the ssr build does not work with async components and how I can fix this?

1 Answer 1

2

When setting up async/code-splitting in VueRouter specifically, you shouldn't be using defineAsyncComponent at all.

https://next.router.vuejs.org/guide/advanced/lazy-loading.html

Simply pass a function that returns an import:

const UserDetails = () => import('./views/UserDetails')

const router = createRouter({
  // ...
  routes: [{ path: '/users/:id', component: UserDetails }],
})

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.