Astro、React、Vue 与 adapters
使用 Astro 客户端脚本、实际 adapters 和保留 scoped facade 的手动桥接实现多技术栈组合。
由独立应用组成的 Astro shell
Astro 可以提供文档内容和 slots,WU 则加载各自通过 Vite 构建的应用。挂载 DOM 的运行时导入应位于由 Astro 处理的 <script> 中,不应在服务器 frontmatter 中执行挂载。
---
const title = 'Laboratorio políglota';
---
<html lang="es">
<head><meta charset="utf-8" /><title>{title}</title></head>
<body>
<main>
<div id="react-slot"></div>
<div id="vue-slot"></div>
</main>
<script>
import { wu } from 'wu-framework';
await wu.init({
apps: [
{ name: 'react-demo', url: '/apps/react-demo', framework: 'react' },
{ name: 'vue-demo', url: '/apps/vue-demo', framework: 'vue' },
],
});
await Promise.all([
wu.mount('react-demo', '#react-slot'),
wu.mount('vue-demo', '#vue-slot'),
]);
</script>
</body>
</html>
两个公共目录都必须包含 manifest 和编译后的资源。要使用具有作用域的状态或事件,请在每个 manifest 中添加请求,并在两份宿主配置中添加相应 grants。
使用 adapter 的 React entry
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { register } from 'wu-framework/adapters/react';
import App from './App.jsx';
const registered = await register('react-demo', App, {
runtime: { React, ReactDOM },
standalone: false,
strictMode: true,
props: { label: 'React' },
});
if (!registered) throw new Error('No se pudo registrar react-demo');
runtime 注入使 adapter 使用与应用相同的实例。从 react-dom/client 导入 ReactDOM:挂载需要 createRoot,即使 React peer 版本范围更宽也是如此。要进行水合,运行时还必须提供 hydrateRoot。
adapter 按名称保存 roots,通过合并 props 实现 update,并在 hydrateRoot 可用时提供水合。standalone 默认为 true,找不到 WU 时会查找 #root;集成的微前端应禁用此项,避免意外挂载到其他位置。
使用 adapter 的 Vue entry
import { register, wuVuePlugin } from 'wu-framework/adapters/vue';
import * as Vue from 'vue';
import App from './App.vue';
const registered = await register('vue-demo', App, {
standalone: false,
props: { label: 'Vue' },
setup(app) {
app.use(wuVuePlugin, { Vue });
},
});
if (!registered) throw new Error('No se pudo registrar vue-demo');
Vue register 通过 adapter 的机制解析运行时;它没有 React 的 runtime 选项。setup 在挂载前接收应用,可用于注册插件或 router。插件接受 Vue 命名空间,以便在没有 bare imports 或 window.Vue 的环境中解析 helpers;仅在 setup 中传入命名空间,不能替代 register 的初始解析。
Vue 提供 reactive 时,更新使用响应式 root props。存在 createSSRApp 时会声明水合支持。standaloneContainer 默认为 #app。
保留作用域权限
在 4.0 中,React/Vue adapters 将 facade 传入组件树,其事件/store hooks 会执行微应用的 grants。请声明 manifest 权限请求和 shell grants。以下手动模式仍适用于自定义 renderer 或显式 appWu 依赖。
对于自定义 renderer,注册显式生命周期并将 facade 作为依赖传递:
import { wu } from 'wu-framework';
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
let root;
let appWu;
let props = {};
const render = () => root.render(React.createElement(App, { ...props, appWu }));
wu.define('react-demo', {
mount(container, context) {
appWu = context.wu;
root = createRoot(container);
render();
},
update(_container, nextProps) {
props = { ...props, ...nextProps };
render();
},
unmount() {
root?.unmount();
root = undefined;
appWu = undefined;
},
});
在 Vue 中,同样的模式使用 createApp(App, { appWu: context.wu })、app.provide('appWu', context.wu) 和 app.unmount()。如果需要动态 props,保留一个 reactive 对象,并在 update slot 中更新。
包内集成
以下 subpaths 属于该包:
| 导入 | 功能 |
|---|---|
wu-framework/integrations/astro |
用于 astro.config.mjs 的工厂 |
wu-framework/integrations/astro/WuShell.astro |
初始化 shell 应用 |
wu-framework/integrations/astro/WuApp.astro |
挂载 slot,可选 lazy |
wu-framework/integrations/astro/WuAppSSR.astro |
服务器渲染与客户端挂载/水合 |
wu-framework/integrations/next |
Next 集成和包内组件 |
从 wu-framework/integrations/astro 导入集成及其组件。Astro wrapper 的类型暴露的配置少于 WuCore;当 shell 需要额外配置时,显式客户端 bootstrap 可控制 grants 和启动顺序。
React、Vue、Angular、Svelte、Preact、Solid、Lit、Vanilla、Alpine、Qwik、Stencil、HTMX 和 Stimulus 都有独立 adapter。选择与你的应用 renderer 对应的 adapter,并检查其 slots:挂载、动态 props、水合和上下文传递在各 adapter 中都有具体契约。
实现参考
导出:package.json;React:src/adapters/react/index.js 和 src/adapters/react/index.js;Vue:src/adapters/vue/index.js 和 src/adapters/vue/index.js;Astro:integrations/astro/index.js、integrations/astro/WuShell.astro、integrations/astro/WuApp.astro。测试:tests/unit/react-runtime-injection.test.js、tests/unit/adapter-conformance.test.js、tests/unit/adapter-slots.test.js、tests/unit/vue-slot-mount-target.test.js。