npm package: @lvetechs/micro-app
Description: 轻量级微前端框架 - 支持函数式和组件式实例化
Author: lvetechs
Latest version: 1.1.3

# @lvetechs/micro-app

轻量级微前端框架，支持函数式实例化和组件式实例化两种模式。

## 安装

```bash
npm install @lvetechs/micro-app
```

## 依赖

本库依赖以下 peerDependencies：

```json
{
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "vue": ">=3.0.0"
  }
}
```

> **注意**：Vue 是可选依赖。如果在 Vue 项目中使用，需要安装 Vue；如果在 React 项目中使用，需要安装 React。

## 在 React 项目中使用

### 方式一：mountMicroApp（推荐）

使用 `mountMicroApp` 简化微应用挂载，自动创建容器：

```tsx
import { mountMicroApp } from '@lvetechs/micro-app'
import { useEffect, useRef } from 'react'

function App() {
  const appRef = useRef<ReturnType<typeof mountMicroApp> | null>(null)

  useEffect(() => {
    // 创建并挂载微应用
    const result = mountMicroApp({
      app: {
        name: 'my-app',
        entry: 'http://localhost:3001',
        container: 'app-container',  // 无需手动创建容器
      },
      onStatusChange: (status) => console.log('状态:', status),
      onError: (error) => console.error('错误:', error),
      onLoad: () => console.log('加载完成'),
    })
    
    result.mount()
    appRef.current = result

    return () => {
      result.destroy()
    }
  }, [])

  return <div id="app-container" />
}
```

### 方式二：createMicroApp

```tsx
import { createMicroApp } from '@lvetechs/micro-app'

// 1. 创建微应用服务
const microApp = createMicroApp({
  apps: [
    {
      name: 'react-app',
      entry: 'http://localhost:3001',
      container: '#react-app-container',
      mode: 'iframe',
    },
    {
      name: 'vue-app',
      entry: 'http://localhost:3002',
      container: '#vue-app-container',
      mode: 'iframe',
    },
  ],
  // 状态变化回调
  onStatusChange: (name, status) => {
    console.log(`[${name}] 状态变化: ${status}`)
  },
  // 错误回调
  onError: (error, appName) => {
    console.error(`[${appName}] 错误:`, error)
  },
  // 加载完成回调
  onLoad: (appName) => {
    console.log(`[${appName}] 加载完成`)
  },
})

// 2. 启动所有应用
microApp.start()

// 3. 或启动指定应用
microApp.startApp('react-app')

// 4. 停止指定应用
microApp.stopApp('react-app')

// 5. 重启指定应用
microApp.restartApp('vue-app')

// 6. 获取单个应用实例
const app = microApp.getApp('react-app')
if (app) {
  app.onStatusChange((status, info) => {
    console.log('状态变化:', status)
  })
}

// 7. 监听所有应用状态变化
const unsubscribe = microApp.onAppChange((name, status) => {
  console.log(`[全局监听] ${name}: ${status}`)
})

// 8. 销毁（在组件卸载时调用）
microApp.destroy()
```

详细示例见：`example/FunctionalExample.tsx`

---

### 模式二：组件式实例化

使用 `MicroApp` 或 `SingleMicroApp` 组件直接在页面中使用。

#### 使用 MicroApp 组件（管理多个子应用）

```tsx
import { MicroApp } from '@lvetechs/micro-app'

function App() {
  const apps = [
    {
      name: 'react-app',
      entry: 'http://localhost:3001',
      container: '#react-app-container',
      mode: 'iframe',
    },
    {
      name: 'vue-app',
      entry: 'http://localhost:3002',
      container: '#vue-app-container',
      mode: 'iframe',
    },
  ]

  return (
    <MicroApp
      apps={apps}
      onStatusChange={(name, status) => {
        console.log(`[${name}] 状态变化: ${status}`)
      }}
      onError={(error, appName) => {
        console.error(`[${appName}] 错误:`, error)
      }}
      onLoad={(appName) => {
        console.log(`[${appName}] 加载完成`)
      }}
    >
      {/* 主应用内容 */}
      <div>这是主应用</div>
    </MicroApp>
  )
}
```

#### 使用 SingleMicroApp 组件（管理单个子应用）

```tsx
import { SingleMicroApp } from '@lvetechs/micro-app'

function App() {
  return (
    <SingleMicroApp
      name="remote-app"
      entry="http://localhost:3001"
      container="#app-container"
      mode="iframe"
      onStatusChange={(status) => console.log(status)}
      onLoad={() => console.log('加载完成')}
      loading={<div>加载中...</div>}
    />
  )
}
```

详细示例见：`example/ComponentExample.tsx`

---

## API 参考

### 类型定义

#### SubAppConfig

| 属性 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | string | 是 | 应用名称，唯一标识 |
| entry | string | 否 | 远程应用入口 URL |
| container | string \| HTMLElement | 是 | 挂载容器 DOM 或选择器 |
| mode | 'iframe' \| 'dynamic' | 否 | 加载模式，默认 iframe |
| priority | number | 否 | 优先级，数值越大越先加载 |
| enabled | boolean | 否 | 是否启用，默认 true |

#### MicroAppStatus

| 状态 | 说明 |
|------|------|
| idle | 空闲：应用还未启动过 |
| starting | 启动中：应用正在初始化 |
| running | 运行中：应用正常运行 |
| error | 错误：应用遇到问题 |
| stopped | 已停止：应用已被停止 |

### MicroAppService 接口

| 方法 | 说明 |
|------|------|
| start() | 启动所有应用 |
| stop() | 停止所有应用 |
| startApp(name) | 启动指定应用 |
| stopApp(name) | 停止指定应用 |
| restartApp(name) | 重启指定应用 |
| getApp(name) | 获取指定应用实例 |
| getAllApps() | 获取所有应用实例 |
| onAppChange(callback) | 监听所有应用状态变化 |
| onStatusChange(name, callback) | 监听指定应用状态变化 |
| destroy() | 销毁实例 |

### MicroAppInstance 接口

| 方法 | 说明 |
|------|------|
| name | 应用名称 |
| getStatus() | 获取应用状态 |
| getInfo() | 获取应用信息 |
| start() | 启动应用 |
| stop() | 停止应用 |
| restart() | 重启应用 |
| updateStatus(status, error?) | 更新状态 |
| onStatusChange(callback) | 订阅状态变化 |
| checkHealth() | 健康检查 |

## 容器要求

无论是函数式还是组件式，都需要提前在页面中准备好容器 DOM：

```html
<!-- 函数式需要手动创建容器 -->
<div id="react-app-container"></div>
<div id="vue-app-container"></div>

<!-- 组件式会自动创建，但容器选择器需要匹配配置 -->
```

## 在 Vue 项目中使用

### 方式一：mountMicroApp（推荐）

使用 `mountMicroApp` 简化微应用挂载，自动创建容器：

```vue
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import { mountMicroApp } from '@lvetechs/micro-app'

const appRef = ref<ReturnType<typeof mountMicroApp> | null>(null)

onMounted(() => {
  // 创建并挂载微应用
  const result = mountMicroApp({
    app: {
      name: 'my-app',
      entry: 'http://localhost:3001',
      container: 'app-container',  // 无需手动创建容器
    },
    onStatusChange: (status) => console.log('状态:', status),
    onError: (error) => console.error('错误:', error),
    onLoad: () => console.log('加载完成'),
  })
  
  result.mount()
  appRef.value = result
})

onUnmounted(() => {
  appRef.value?.destroy()
})
</script>

<template>
  <div id="app-container" />
</template>
```

### 方式二：createMicroApp

与 React 项目相同，使用 `createMicroApp` 函数：

```vue
<script setup lang="ts">
import { createMicroApp } from '@lvetechs/micro-app'

const microApp = createMicroApp({
  apps: [
    {
      name: 'react-app',
      entry: 'http://localhost:3001',
      container: '#react-app-container',
      mode: 'iframe',
    },
  ],
  onStatusChange: (name, status) => {
    console.log(`[${name}] 状态变化: ${status}`)
  },
})

// 启动应用
microApp.startApp('react-app')
</script>

<template>
  <div id="react-app-container"></div>
</template>
```

### 方式二：使用 Vue 组件

在 Vue 3 项目中可以使用 `MicroAppVue.vue` 组件：

```vue
<script setup lang="ts">
import { ref } from 'vue'
import MicroAppVue from '@lvetechs/micro-app/dist/components/MicroAppVue.vue'

const apps = [
  {
    name: 'react-app',
    entry: 'http://localhost:3001',
    container: '#vue-app-container',
    active_rule: '/app/react',
  },
  {
    name: 'vue-app',
    entry: 'http://localhost:3002',
    container: '#vue-app-container',
    active_rule: '/app/vue',
  },
]

const activeApp = ref(apps[0].name)
</script>

<template>
  <div>
    <!-- 切换按钮 -->
    <button @click="activeApp = 'react-app'">React App</button>
    <button @click="activeApp = 'vue-app'">Vue App</button>
    
    <!-- 微应用组件 -->
    <MicroAppVue
      :apps="apps"
      :active-app="activeApp"
      @status-change="(name, status) => console.log(name, status)"
    />
  </div>
</template>
```

> **注意**：使用 Vue 组件时，需要在项目中安装 `@vitejs/plugin-vue`。

## 打包

```bash
# 构建
npm run build

# 开发模式（监听文件变化）
npm run dev
```

## License

MIT