使用 s-s-r 时无法在 vue3 中使用异步组件

Posted

技术标签:

【中文标题】使用 s-s-r 时无法在 vue3 中使用异步组件【英文标题】:Can't use async components in vue3 when using s-s-r 【发布时间】:2021-02-18 08:26:40 【问题描述】:

我有一个安装了 vue-router 和 vuex 的 vue 3 应用程序,运行良好。 现在我正在尝试为其集成服务器端渲染。在我集成 defineAsyncComponent() 以延迟加载我的路线之前,这也运行良好。

一旦我从这个路由器实现切换:

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
            ,
        ]
    );

到带有异步组件的变体:

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
            ,
        ]
    );


当我尝试在服务器端渲染应用程序时出现以下错误(客户端仍然运行良好并且异步组件按预期加载):

/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)

这是我用来构建一切的 vite 配置:

const s-s-rBuild, 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 s-s-rBuild(
        mode: 'development',
        rollupInputOptions: 
            inlineDynamicImports: true,
            input: './resources/js/entry-server.js'
        ,
        outDir: 'public/build/server',
    )

    process.exit();
)()

这是我的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);
    );
);

您知道为什么 s-s-r 构建不适用于异步组件以及如何解决这个问题吗?

【问题讨论】:

【参考方案1】:

当专门在 VueRouter 中设置异步/代码拆分时,您根本不应该使用 defineAsyncComponent。

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

只需传递一个返回导入的函数:

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

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

【讨论】:

以上是关于使用 s-s-r 时无法在 vue3 中使用异步组件的主要内容,如果未能解决你的问题,请参考以下文章

Vue3的动态组件和异步组价

react-redux s-s-r 异步 api 调用未按预期工作

在带有路由器视图的 Vue3 中使用异步设置()时我得到了空白

Angular/Rxjs 管道异步不适用于 s-s-r?

无法在 s-s-r 中执行 https 请求

vue3教程