从一个 SvelteKit App 调用组件到另一个 SvelteKit App
Call component from one SvelteKit App to another SvelteKit App
注意:我已将我的 Sapper 应用程序迁移到 SvelteKit(下面的更新 3),因此现在正在寻找 SvelteKit 的解决方案。
我有多个使用 Sapper 构建的 MFE(微前端),它们位于不同的服务器下。我想在另一个 MFE 中 call/render 的一个 MFE 中有一个精巧的组件(呈现 HTML 内容)。我怎样才能做到这一点?我在我的本地同时尝试了 running/serving 两个 MFE,并进行了一次获取(路由加载组件),但它 returns 响应中的一个 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)
即使我最终解决了这些基本路径 URL 问题,它是否仍然适用于在一个页面上启动 2 个 Sapper 应用程序?
更新 2:
我以某种方式设法从请求内容的地方为 MFE 添加了静态 baseURL,现在我遇到了水化问题,因为 Sapper 无法在一页中水化 2 个 Sapper 应用程序。
更新 3:
我已将我的 Sapper 应用程序迁移到 SvelteKit。因此,现在正在寻找有关如何使用 SvelteKit 实现这一目标的建议!
call/import 从一个 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}`)
}
}
}
此 returns 包含 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),但希望它能奏效!
注意:我已将我的 Sapper 应用程序迁移到 SvelteKit(下面的更新 3),因此现在正在寻找 SvelteKit 的解决方案。 我有多个使用 Sapper 构建的 MFE(微前端),它们位于不同的服务器下。我想在另一个 MFE 中 call/render 的一个 MFE 中有一个精巧的组件(呈现 HTML 内容)。我怎样才能做到这一点?我在我的本地同时尝试了 running/serving 两个 MFE,并进行了一次获取(路由加载组件),但它 returns 响应中的一个 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)
即使我最终解决了这些基本路径 URL 问题,它是否仍然适用于在一个页面上启动 2 个 Sapper 应用程序?
更新 2:
我以某种方式设法从请求内容的地方为 MFE 添加了静态 baseURL,现在我遇到了水化问题,因为 Sapper 无法在一页中水化 2 个 Sapper 应用程序。
更新 3: 我已将我的 Sapper 应用程序迁移到 SvelteKit。因此,现在正在寻找有关如何使用 SvelteKit 实现这一目标的建议!
call/import 从一个 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}`)
}
}
}
{
"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}