npm package: @spes/react-plugins
Description: Use your react component as plugins!
Author: kaniel
Latest version: 0.0.8

# @spes/react-plugins

> 将 React 组件作为插件使用，专为超大型前端项目设计的插件化架构解决方案

[![NPM](https://img.shields.io/npm/v/@spes/react-plugins.svg)](https://www.npmjs.com/package/@spes/react-plugins) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)

## 核心特性

- **模块化架构**：支持多模块、多命名空间的插件管理
- **依赖解析**：自动解析插件依赖关系，支持版本约束和可选依赖
- **循环依赖检测**：运行时和构建时双重检测，提供可视化报告
- **生命周期管理**：完整的插件生命周期（注册→激活→停用→销毁）
- **事件系统**：基于命名空间的事件总线，支持插件间通信
- **虚拟化渲染**：支持大量插件的虚拟化渲染，优化性能
- **严格类型**：完整的 TypeScript 类型支持
- **Webpack 插件**：构建时循环依赖检测和报告生成

## 安装

```bash
npm install --save @spes/react-plugins
```

依赖要求：
- React >= 16.8.0（支持 Hooks）
- TypeScript >= 3.7（推荐）

## 快速开始

### 1. 创建 PluginStore

```typescript
import { PluginStore } from '@spes/react-plugins';

const store = new PluginStore();
export default store;
```

### 2. 包裹应用组件

```tsx
import React from 'react';
import { PluginStoreProvider } from '@spes/react-plugins';
import store from './pluginStore';
import App from './App';

const Root = () => (
  <PluginStoreProvider store={store}>
    <App />
  </PluginStoreProvider>
);

export default Root;
```

### 3. 注册插件

```tsx
import store from './pluginStore';
import MyWidget from './components/MyWidget';

// 基础注册
store.registerPlugin('sidebar', MyWidget, 'my-widget', 10);

// 带依赖的注册
store.registerPlugin('sidebar', {
  component: MyWidget,
  name: 'my-widget',
  version: '1.0.0',
  dependencies: ['user-profile@^1.0.0'],  // 依赖其他插件
  optionalDependencies: ['theme-plugin']  // 可选依赖
});

// 完整配置（推荐）
store.registerPlugin('sidebar', {
  component: MyWidget,
  name: 'my-widget',
  version: '1.0.0',
  module: 'user-module',
  dependencies: ['user-profile'],
  auto: true,      // 自动加载
  lazy: true       // 懒加载
});
```

### 4. 使用插件

```tsx
import React from 'react';
import { usePlugins } from '@spes/react-plugins';

const Sidebar = () => {
  const plugins = usePlugins('sidebar');
  
  return (
    <div className="sidebar">
      {plugins.map((Plugin, index) => (
        <Plugin key={index} />
      ))}
    </div>
  );
};
```

## 核心 API

### PluginStore

插件存储的核心类，管理所有插件的注册、依赖解析和生命周期。

```typescript
class PluginStore {
  // 基础注册
  registerPlugin(
    section: string,
    component: ComponentType | ReactElement,
    name: string,
    priority?: number
  ): void;

  // 选项式注册（推荐）
  registerPlugin(
    section: string,
    options: PluginOption
  ): void;

  // 移除插件
  removePlugin(section: string, name: string): void;

  // 获取插件
  getPlugin(section: string, name: string): PluginOption | undefined;
  getPlugins(section: string): PluginOption[];
  getSections(): string[];

  // 事件系统
  on(event: string, callback: PluginEventCallback, namespace?: string): () => void;
  emit(event: string, data?: any): void;
  broadcast(section: string, event: string, data?: any): void;
}
```

### Hooks

#### usePlugins

获取指定 section 的所有插件组件。

```tsx
const plugins = usePlugins('sidebar');
```

#### usePluginStatus

监听插件状态变化。

```tsx
const status = usePluginStatus('sidebar', 'my-widget');
// status: { loaded: boolean; version?: string; dependencies: {...} }
```

#### usePluginEvent

订阅插件事件。

```tsx
usePluginEvent('plugin:registered', (data) => {
  console.log('Plugin registered:', data);
});
```

#### usePluginDependencies

获取插件依赖信息。

```tsx
const deps = usePluginDependencies('my-widget');
// deps: { satisfied: boolean; missing: string[]; ... }
```

#### useVirtualPlugins

虚拟化渲染大量插件。

```tsx
const { virtualItems, containerRef, totalHeight } = useVirtualPlugins({
  section: 'sidebar',
  itemHeight: 50,
  overscan: 5
});
```

## 高级功能

### 模块管理

适用于超大型项目的模块化管理：

```typescript
import { ModuleManager } from '@spes/react-plugins';

const manager = new ModuleManager();

// 注册模块
manager.registerModule({
  name: 'billing',
  version: '2.0.0',
  dependencies: ['user', 'auth']  // 依赖其他模块
});

// 检查模块依赖
const result = manager.checkModuleDependencies('billing');
console.log(result.satisfied);  // true/false

// 获取加载顺序（拓扑排序）
const order = manager.resolveModuleOrder();
// ['auth', 'user', 'billing']
```

### 生命周期管理

```typescript
import { PluginLifecycle } from '@spes/react-plugins';

const lifecycle = new PluginLifecycle();

// 订阅生命周期事件
lifecycle.subscribe((event) => {
  console.log(event.type, event.pluginName, event.currentState);
});

// 手动控制生命周期
await lifecycle.activate('my-plugin');
await lifecycle.deactivate('my-plugin');
await lifecycle.destroy('my-plugin');
```

### 循环依赖检测

```typescript
import { CircularDependencyDetector } from '@spes/react-plugins';

const detector = new CircularDependencyDetector();

// 添加插件
detector.addPlugin({
  metadata: { name: 'plugin-a', version: '1.0.0' },
  component: ComponentA,
  dependencies: ['plugin-b']
});

// 检测循环依赖
const report = detector.detectAtRuntime();
if (report.hasCircular) {
  console.log('循环链:', report.cycles);
  console.log('严重程度:', report.severity);
}

// 生成可视化图表
const mermaidDiagram = detector.generateMermaidDiagram();
const dotGraph = detector.generateDotGraph();
```

### Webpack 插件

构建时循环依赖检测：

```javascript
// webpack.config.js
const { ReactPluginsWebpackPlugin } = require('@spes/react-plugins/webpack');

module.exports = {
  plugins: [
    new ReactPluginsWebpackPlugin({
      detectCircularDependency: true,
      circularDependencyThreshold: 0,  // 超过此数量报错
      ignoreNodeModules: true,
      generateReport: true,
      reportOutputPath: 'plugin-dependency-report.json',
      generateVisualization: true,  // 生成 Mermaid/DOT 图表
      failOnError: 'warn'  // 'error' | 'warn' | 'silent'
    })
  ]
};
```

## 类型定义

### PluginOption

```typescript
interface PluginOption {
  // ========== 核心属性 ==========
  component: ComponentType | ReactElement;
  name?: string;
  
  // ========== 模块属性 ==========
  module?: string;
  section?: string;
  
  // ========== 版本和元数据 ==========
  version?: string;
  displayName?: string;
  description?: string;
  
  // ========== 依赖控制 ==========
  dependencies?: string[];
  optionalDependencies?: string[];
  
  // ========== 加载控制（声明式优先级） ==========
  auto?: boolean;        // 自动加载
  before?: string;       // 在此插件之前渲染
  after?: string;        // 在此插件之后渲染
  
  // ========== 懒加载 ==========
  lazy?: boolean;
  lazyConfig?: {
    preload?: 'immediate' | 'lazy' | 'idle' | 'visible';
    timeout?: number;
  };
  placeholder?: ComponentType;  // 懒加载占位符
  
  // ========== 权限控制 ==========
  permissions?: string[];
  roles?: string[];
  
  // ========== 性能预算 ==========
  memoryBudget?: number;   // 内存预算（MB）
  renderBudget?: number;   // 渲染性能预算（ms）
  
  // ========== 错误处理 ==========
  errorBoundary?: ComponentType<{ error: Error; reset: () => void }>;
  throwOnError?: boolean;
  
  // ========== 生命周期 ==========
  lifecycle?: {
    beforeActivate?: () => boolean | Promise<boolean>;
    onActivate?: () => void | Promise<void>;
    beforeDeactivate?: () => boolean | Promise<boolean>;
    onDeactivate?: () => void | Promise<void>;
    onDestroy?: () => void;
  };
  
  // ========== 国际化 ==========
  i18n?: {
    languages: string[];
  };
  
  // ========== 调试 ==========
  tags?: string[];
  debug?: {
    verbose?: boolean;
    performance?: boolean;
  };
  
  // ========== 作者信息 ==========
  author?: {
    name: string;
    email?: string;
    organization?: string;
  };
  
  // ========== 时间戳 ==========
  createdAt?: string;
  updatedAt?: string;
}
```

### PluginState

```typescript
enum PluginState {
  REGISTERED = 'registered',    // 已注册但未激活
  ACTIVATING = 'activating',    // 正在激活
  ACTIVE = 'active',            // 已激活
  DEACTIVATING = 'deactivating', // 正在停用
  INACTIVE = 'inactive',        // 已停用
  ERROR = 'error',              // 发生错误
  DESTROYED = 'destroyed'       // 已销毁
}
```

## 错误处理

```typescript
import {
  PluginError,
  PluginDependencyError,
  PluginVersionError,
  PluginCircularDependencyError,
  PluginNotFoundError
} from '@spes/react-plugins';

try {
  store.registerPlugin('section', config);
} catch (error) {
  if (error instanceof PluginCircularDependencyError) {
    console.log('循环链:', error.cycle);
  } else if (error instanceof PluginDependencyError) {
    console.log('缺失依赖:', error.missingDependencies);
  }
}
```

## 性能优化

### 虚拟化渲染

```tsx
import { useVirtualPlugins } from '@spes/react-plugins';

const VirtualSidebar = () => {
  const { virtualItems, containerRef, totalHeight } = useVirtualPlugins({
    section: 'sidebar',
    itemHeight: 60,
    overscan: 3,
    containerHeight: 600
  });

  return (
    <div ref={containerRef} style={{ height: 600, overflow: 'auto' }}>
      <div style={{ height: totalHeight }}>
        {virtualItems.map(({ item, style, index }) => (
          <div key={index} style={style}>
            <item.component />
          </div>
        ))}
      </div>
    </div>
  );
};
```

### 懒加载

```typescript
store.registerPlugin('section', {
  component: LazyComponent,
  name: 'lazy-plugin',
  version: '1.0.0',
  lazy: true,
  lazyConfig: {
    preload: 'visible',
    timeout: 5000
  }
});
```

## 热插拔架构（Base + 子模块）

适用于微前端、插件化系统场景：

```typescript
// Base 项目
import { HotPlugManager, PluginStore, ModuleManager } from '@spes/react-plugins';

const store = new PluginStore();
const moduleManager = new ModuleManager();
const hotPlug = new HotPlugManager(store, moduleManager, {
  interval: 3000,      // 3秒检测一次
  autoRegister: true,  // 自动注册
  autoUnregister: true // 自动卸载
});

hotPlug.startDetection();
```

```typescript
// 子模块（独立构建部署）
const ModuleADeclaration = {
  version: '1.0.0',
  plugins: [
    {
      section: 'sidebar',
      config: { component: Widget, name: 'widget', version: '1.0.0' }
    }
  ]
};

// 自动注册到 Base
(window as any).__PLUGIN_MODULES__ = {
  ...(window as any).__PLUGIN_MODULES__,
  'module-a': ModuleADeclaration
};
```

### 快速生成子模块

使用 CLI 工具快速创建符合规范的子模块：

```bash
# 生成模块
node scripts/generate-plugin.js \
  --name=order-module \
  --component=OrderList \
  --section=dashboard \
  --version=1.0.0 \
  --lazy=true

# 构建模块
cd order-module
npm install
npm run build

# 部署到 Nginx
cp dist/order-module.js /var/www/plugins/
```

## 远程动态加载（Nginx 部署）

支持从服务端动态加载插件：

```typescript
import { RemotePluginLoader } from '@spes/react-plugins';

const loader = new RemotePluginLoader(store, moduleManager, {
  pluginsEndpoint: '/api/plugins',   // 插件列表 API
  pluginsBasePath: '/plugins/',       // 插件文件路径
  checkInterval: 30000                // 30秒检测一次
});

// 启动自动加载
await loader.start();

// 手动加载
await loader.loadPlugin({ name: 'module-a', file: 'module-a.js', version: '1.0.0' });

// 上传并加载
await loader.uploadAndLoad(file);
```

## 示例项目

查看 `example` 目录获取完整示例：

```bash
cd example
npm install
npm start
```

示例包含：
- 基础插件注册和使用
- 模块化管理
- 依赖注入
- 事件通信
- 虚拟化渲染
- 热插拔架构
- 远程动态加载

## 技术限制

1. **React 版本**：需要 React 16.8+（Hooks 支持）
2. **TypeScript**：推荐使用 TS 3.7+ 以获得最佳类型推断
3. **浏览器支持**：依赖 ES2015+ 特性，IE 需要 polyfill
4. **性能**：大量插件（>1000）建议使用虚拟化渲染

## 架构图

```
+-------------------------------------------------------------+
|                      React Plugins                          |
+-------------------------------------------------------------+
|  +--------------+  +--------------+  +--------------+      |
|  |   Hooks      |  |  Components  |  |    Store     |      |
|  |  usePlugins  |  |   Plugins    |  | PluginStore  |      |
|  | usePluginEvent|  |   Provider   |  |              |      |
|  +------+-------+  +------+-------+  +------+-------+      |
|         +-----------------+------------------+              |
|                           |                                 |
|  +------------------------+------------------------+       |
|  |                   Core Layer                      |       |
|  |  +--------------+ +--------------+ +----------+  |       |
|  |  |ModuleManager | |DependencyResolver| |PluginLifecycle|  |
|  |  +--------------+ +--------------+ +----------+  |       |
|  |  +--------------+ +--------------+ +----------+  |       |
|  |  |CircularDependency| |   EventBus   | |HotPlugManager|  |
|  |  |   Detector   | +--------------+ +----------+  |       |
|  |  +--------------+ +--------------+ +----------+  |       |
|  |  |  RemotePluginLoader  |                        |       |
|  |  +---------------------+                         |       |
|  +--------------------------------------------------+       |
|                           |                                 |
|  +------------------------+------------------------+       |
|  |                   Utils Layer                     |       |
|  |  +--------------+ +--------------+ +----------+  |       |
|  |  | pluginErrors | |dependencyManager| |  store   |  |    |
|  |  +--------------+ +--------------+ +----------+  |       |
|  +--------------------------------------------------+       |
+-------------------------------------------------------------+
```

## 许可证

MIT