# Astro、React、Vue 与 adapters

使用 Astro 客户端脚本、实际 adapters 和保留 scoped facade 的手动桥接实现多技术栈组合。

<span id="un-shell-astro-con-apps-independientes"></span>

<span class="section-anchor" id="section-1"></span>

## 由独立应用组成的 Astro shell

Astro 可以提供文档内容和 slots，WU 则加载各自通过 Vite 构建的应用。挂载 DOM 的运行时导入应位于由 Astro 处理的 `<script>` 中，不应在服务器 frontmatter 中执行挂载。

```astro
---
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。

<span id="entry-react-con-adapter"></span>

<span class="section-anchor" id="section-2"></span>

## 使用 adapter 的 React entry

```jsx
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`；集成的微前端应禁用此项，避免意外挂载到其他位置。

<span id="entry-vue-con-adapter"></span>

<span class="section-anchor" id="section-3"></span>

## 使用 adapter 的 Vue entry

```js
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`。

<span id="conservar-la-autoridad-scoped"></span>

<span class="section-anchor" id="section-4"></span>

## 保留作用域权限

在 4.0 中，React/Vue adapters 将 facade 传入组件树，其事件/store hooks 会执行微应用的 grants。请声明 manifest 权限请求和 shell grants。以下手动模式仍适用于自定义 renderer 或显式 `appWu` 依赖。

对于自定义 renderer，注册显式生命周期并将 facade 作为依赖传递：

```jsx
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 中更新。

<span id="integraciones-incluidas-en-el-paquete"></span>

<span class="section-anchor" id="section-5"></span>

## 包内集成

以下 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 中都有具体契约。

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-6"></span>

## 实现参考

导出：`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`。