WU / 文档通用微前端
中文

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。

一起完善 WU

发现了问题?有新的想法?

你的使用体验能让 WU 变得更好。告诉我们遇到的问题,或支持项目的持续开发。