从一个 SvelteKit App 调用组件到另一个 SvelteKit App

问题描述

注意:我已将我的 Sapper 应用程序迁移到 svelteKit(下面的更新 3),因此现在正在寻找 svelteKit 的解决方案。 我有多个使用 Sapper 构建的 MFE(微前端),它们位于不同的服务器下。我想在另一个 MFE 中调用/渲染一个 MFE 中有一个 svelte 组件(呈现 HTML 内容)。我怎样才能做到这一点?我尝试在本地同时运行/提供两个 MFE 并执行了 fetch(route-that-loads-component),但它在响应中返回了一个 POJO,我不知道如何处理它:>

Response {
  size: 0,timeout: 0,[Symbol(Body internals)]: {
    body: Gunzip {
      _writeState: [Uint32Array],_readableState: [ReadableState],_events: [Object: null prototype],_eventsCount: 5,_maxListeners: undefined,_writableState: [WritableState],allowHalfOpen: true,bytesWritten: 0,_handle: [Zlib],_outBuffer: <Buffer 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 f7 7f 00 00 41 ff e2 55 48 89 e5 56 57 48 81 ec 10 01 00 00 48 89 75 e8 49 3b 65 e0 0f 86 fb 11 00 00 ... 16334 more bytes>,_outOffset: 0,_chunkSize: 16384,_defaultFlushFlag: 2,_finishFlushFlag: 2,_defaultFullFlushFlag: 3,_info: undefined,_maxOutputLength: 4294967295,_level: -1,_strategy: 0,[Symbol(kCapture)]: false,[Symbol(kTransformState)]: [Object],[Symbol(kError)]: null
    },disturbed: false,error: null
  },[Symbol(Response internals)]: {
    url: 'http://localhost:3000/mfe/content-mfe/content/testrouteasset1',status: 200,statusText: 'OK',headers: Headers { [Symbol(map)]: [Object: null prototype] },counter: 0
  }
}

更新 1:

我可以通过执行 response.text() 得到 MFE 的响应,它是这样的:

<!doctype html>
<html lang="en">
<head>
        <Meta charset="utf-8">
        <Meta name="viewport" content="width=device-width,initial-scale=1.0">
        <Meta name="theme-color" content="#333333">

        <base href="/mfe/content-mfe/">

        <link rel="stylesheet" href="global.css">
        <link rel="manifest" href="manifest.json" crossorigin="use-credentials">
        <link rel="icon" type="image/png" href="favicon.png">

        <!-- Sapper creates a <script> tag containing `src/client.js`
             and anything else it needs to hydrate the app and
             initialise the router -->
        <script>__SAPPER__={baseUrl:"/mfe/content-mfe",preloaded:[void 0,null,{}]};if('serviceWorker' in navigator)navigator.serviceWorker.register('/mfe/content-mfe/service-worker.js');var s=document.createElement("script");try{new Function("if(0)import('')")();s.src="/mfe/content-mfe/client/client.1dc273d9.js";s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="/mfe/content-mfe/client/shimport@2.0.4.js";s.setAttribute("data-main","/mfe/content-mfe/client/client.1dc273d9.js")}document.head.appendChild(s)</script>   

        <!-- Sapper generates a <style> tag containing critical CSS
             for the current page. CSS for the rest of the app is
             lazily loaded when it precaches secondary pages -->
        <link rel="stylesheet" href="client/client-a7fe6d9e.css"><link rel="stylesheet" href="client/FieldErrorMessage-bce587e1.css">

        <!-- This contains the contents of the <svelte:head> component,if
             the current page has one -->

</head>
<body>
        <!-- The application will be rendered inside this element,because `src/client.js` references it -->
        <div id="mfe-content">


<main><slot></slot></main></div>
</body>
</html>

但是,Sapper 正在替换向调用 MFE 的 baseURL 发送响应的 MFE 的 baseURL,使其不可水合,因为 client.js 和 client.css 不可达 (404s)

enter image description here

即使我最终解决了这些基本路径 URL 问题,它仍然可以在一个页面上启动 2 个 Sapper 应用程序吗?

更新 2:

我设法为 MFE 添加了静态 baseURL,从中请求内容,现在我遇到了水化问题,因为 Sapper 无法在一页中水化 2 个 Sapper 应用程序。

更新 3: 我已将我的 Sapper 应用程序迁移到 svelteKit。所以现在就寻找关于如何使用 svelteKit 实现这一目标的建议!

将组件从一个 MFE 调用/导入到另一个 MFE 的任何其他解决方案或将不胜感激!

解决方法

迁移到 SvelteKit(问题中的更新 3)后,我能够通过创建端点(路由文件夹中的 .js 文件)、导入所需的组件并导出它来解决此问题,如下所示:

export async function get({ query,page }) {
    const ASSET = (await import("../../assets/myasset.svelte")).default;

    if (ASSET) {
        let renderedAsset = Asset.render();
        return {
            body: { asset: renderedAsset }
        };
    } else {
        return {
            status: data.status,error: new Error(`Could not load ${response}`)
        }
    }
}
这将返回一个包含 HTML 和 CSS 代码的对象:

{
    "asset": {
        "html": "<h1 class=\"s-ZmOKpGJa32Cj\">Hello!    \n</h1>","css": {
            "code": "h1.s-ZmOKpGJa32Cj{color:blue}.s-ZmOKpGJa32Cj{}","map": null
        },"head": ""
    }
}

最后可以像这样渲染到 DOM:

<script context="module">
    export async function load({ fetch }) {
        let status,Final;
        const Asset = await fetch('path-to-the-endpoint');
        if (Asset && Asset.status === 404) {
            return (status = 'Asset not found');
        }
        if (Asset && Asset.ok) {
            Final = await Asset.json();
            return {
                props: {
                    Final: Final,status: 'Asset is OK',},};
        } else {
            return {
                props: {
                    status: 'Okay,no prop.',};
        }
    }
</script>

<script>
    export let Final,status;
</script>
{status}

{@html `<${''}style>${Final.asset.css.code }</${''}style>` }

{@html Final.asset.html}
这在 SvelteKit 中非常有效。但是,我还没有测试这在 Sapper 中是否有效(因为我已经离开了 Sapper),但希望它应该有效!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...