从头开始的 Vue SSR - 在客户端加载服务器 webpack 包时出现问题

问题描述 投票:0回答:1

我正在尝试构建文档生成器服务,由于灵活性等原因,我的文档模板是用 Vue 编写的。

上下文(请随意跳到问题部分)

  1. 客户使用我为此目的编写的库在 Vue 中编写他的文档模板
  2. 客户端将此模板上传到我的服务器。之后,使用 webpack 作为 commonjs 模块自动构建此模板,并使用转译的 vue 组件作为默认导出。 供参考 - 以下是模板的样子:
{
    __name: "NajomnaZmluva",
    props: {
        "landlords": {
            "required": true
        },
        "tenants": {
            "required": true
        },
        "contractedProperty": {
            "required": true
        },
        "edit": { 
            "required": false,
            "default": false
        }
    },
    __file: "templates/reality_module/NajomnaZmluva.vue",
    setup: ƒsetup(__props, { expose: __expose }) { ... }
    ssrRender: ƒssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { ... }
}
  1. 成功构建后,客户端可以使用 props 作为有效负载向
    /render
    ep 发送调用。
  2. 此 EP 返回模板的渲染 HTML 字符串。

这效果很好,但并不能完全满足我的需求 - 我需要以某种方式在前端编辑此模板,这样如果有什么问题,我可以纠正它或覆盖它。为此,我在我的 templater vue 库中添加了更强大的功能,可以通过将

edit
属性切换为
true
来触发 - 这会将我的模板转换为成熟的反应式文档编辑器。

问题

如何从服务器在客户端导入已转译的 webpack 包(作为服务器上的静态资源)并从中提取默认导出 - 这是我可以传递给此代码的 Vue 组件:

  private hydrateDocument(
    component: TranspiledComponent,
    selector: string,
    tp: Record<string, any>
  ) {
    createApp({
      render() {
        return h(component, tp);
      },
    }).mount(selector);
  }

我尝试过的

  1. axios 调用 - 这只返回原始字符串。我不知道我能用它做什么以及是否可以做一些事情
  2. eval
    - 尝试将字符串传递给
    eval
    ,但不幸的是,它导致了错误......这只是一个实验,我不想使用
    eval
  3. 将字符串转换为
    Blob
    - 然后转换为
    ObjectURL
    ,我已将其传递给
    import
    语句 - 浏览器拒绝了它

我不知道如何加载我的转译组件,以便我可以在客户端对其进行水合。 nuxt 和其他 SSR fws 如何处理这个问题?

vue.js webpack nuxt.js bundle server-side-rendering
1个回答
0
投票

为了实现您的目标,您需要在客户端动态加载并执行转译的 Vue 组件。您可以采取以下一般方法:

  1. 服务器端:将转译的 Vue 组件作为服务器中的静态资产提供服务。

  2. 客户端:使用 HTTP 请求获取转译的 Vue 组件,一旦在客户端获得了组件代码,就需要动态评估它。

以下是处理客户端代码的方法:

import axios from 'axios';
import { createApp, h } from 'vue'; 

async function fetchAndRenderComponent() {
    try {
        const response = await axios.get('/path/to/transpiled/component');
        const componentCode = response.data; // Assuming the response contains the component code as a string

        // Dynamically evaluate the component code
        const componentModule = new Function('module', componentCode);
        const { default: TranspiledComponent } = componentModule({}); // Pass any required globals if necessary
        
        // Now you can use the TranspiledComponent
        const app = createApp({
            render() {
                return h(TranspiledComponent, {});
            },
        });

        app.mount('#app'); // Replace '#app' with your selector
    } catch (error) {
        console.error('Error fetching or rendering component:', error);
    }
}

fetchAndRenderComponent();
© www.soinside.com 2019 - 2024. All rights reserved.