CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-umi

Enterprise-level, plugin-based React application framework with out-of-the-box functionality including routing, building, deployment, testing, and linting capabilities

Pending
Overview
Eval results
Files

plugin-system.mddocs/

Plugin System

Comprehensive plugin system supporting both server-side and client-side plugins with hook management, plugin registration, and execution control.

Capabilities

Plugin Application Types

Enumeration defining how plugins are applied and executed.

/**
 * Plugin application types for different execution patterns
 */
enum ApplyPluginsType {
  compose = "compose", // Function composition pattern
  modify = "modify",   // Value modification pattern
  event = "event"      // Event-driven pattern
}

Plugin Manager

Client-side plugin manager for registering and executing plugins with type safety and validation.

/**
 * Client-side plugin manager for hook registration and execution
 */
class PluginManager {
  /**
   * Creates a new plugin manager instance
   * @param opts - Configuration with valid hook keys
   */
  constructor(opts: PluginManagerOpts);

  /**
   * Register a plugin with the manager
   * @param plugin - Plugin definition with apply methods
   */
  register(plugin: IPlugin): void;

  /**
   * Get hooks for a specific key, supporting dot notation
   * @param keyWithDot - Hook key, optionally with member access (e.g., "key.member")
   * @returns Array of registered hooks for the key
   */
  getHooks(keyWithDot: string): any[];

  /**
   * Apply plugins for a specific hook key
   * @param opts - Plugin application options
   * @returns Result based on application type
   */
  applyPlugins(opts: ApplyPluginsOpts): any;

  /**
   * Create and initialize a plugin manager with plugins
   * @param opts - Manager configuration with plugins
   * @returns Configured plugin manager instance
   */
  static create(opts: CreatePluginManagerOpts): PluginManager;
}

interface PluginManagerOpts {
  validKeys: string[]; // Array of valid hook keys
}

interface IPlugin {
  path?: string; // Plugin file path for debugging
  apply: Record<string, any>; // Hook implementations
}

interface ApplyPluginsOpts {
  key: string; // Hook key to apply
  type: ApplyPluginsType; // Application type
  initialValue?: any; // Initial value for modify type
  args?: object; // Arguments passed to hooks
  async?: boolean; // Whether to use async execution
}

interface CreatePluginManagerOpts {
  validKeys: string[];
  plugins: IPlugin[];
}

Usage Examples:

import { PluginManager, ApplyPluginsType } from "umi/client";

// Create plugin manager
const pluginManager = new PluginManager({
  validKeys: ["modifyRoutes", "onRouteChange", "render"],
});

// Register a plugin
pluginManager.register({
  path: "./my-plugin.js",
  apply: {
    modifyRoutes: (routes) => {
      return routes.concat([
        { path: "/custom", component: "CustomPage" }
      ]);
    },
    onRouteChange: ({ location }) => {
      console.log("Route changed to:", location.pathname);
    },
  },
});

// Apply plugins with modify pattern
const modifiedRoutes = pluginManager.applyPlugins({
  key: "modifyRoutes",
  type: ApplyPluginsType.modify,
  initialValue: baseRoutes,
});

// Apply plugins with event pattern
await pluginManager.applyPlugins({
  key: "onRouteChange",
  type: ApplyPluginsType.event,
  args: { location: { pathname: "/new-route" } },
});

// Create manager with plugins in one step
const manager = PluginManager.create({
  validKeys: ["beforeRender", "afterRender"],
  plugins: [
    {
      apply: {
        beforeRender: () => console.log("Before render"),
        afterRender: () => console.log("After render"),
      },
    },
  ],
});

Plugin Utilities

Utility functions and exports for plugin development and server-side functionality.

/**
 * Create server routes for API handling
 * Re-exported from @umijs/server
 */
function createServerRoutes(...args: any[]): any;

/**
 * Express server instance
 * Re-exported from @umijs/bundler-utils
 */
const express: any;

/**
 * HTTP proxy middleware for development
 * Re-exported from @umijs/bundler-utils
 */
const httpProxyMiddleware: any;

// All utility functions from @umijs/utils are also available
// Including file system utilities, logger, validation, etc.

Usage Examples:

import { 
  createServerRoutes, 
  express, 
  httpProxyMiddleware,
  logger 
} from "umi/plugin-utils";

// Create API routes
const routes = createServerRoutes({
  "/api/users": "./api/users",
  "/api/auth": "./api/auth",
});

// Use express for custom server setup
const app = express();
app.use("/api", routes);

// Add proxy middleware
app.use(
  "/proxy",
  httpProxyMiddleware({
    target: "http://localhost:8080",
    changeOrigin: true,
  })
);

// Use logger utility
logger.info("Plugin initialized successfully");

Client Utilities

Low-level utilities for client-side plugin functionality.

/**
 * Assertion utility for runtime validation
 * @param value - Value to test
 * @param message - Error message if assertion fails
 */
function assert(value: any, message: string): void;

/**
 * Function composition utility for creating complex operations
 * @param opts - Composition options with functions and arguments
 * @returns Composed function
 */
function compose(opts: ComposeOpts): Function;

/**
 * Promise detection utility
 * @param obj - Object to test for promise-like behavior
 * @returns True if object has then method
 */
function isPromiseLike(obj: any): boolean;

interface ComposeOpts {
  fns: Function[]; // Functions to compose
  args?: any; // Arguments to pass through
}

Usage Examples:

import { assert, compose, isPromiseLike } from "umi/client";

// Runtime validation
assert(config.routes, "Routes configuration is required");

// Function composition
const pipeline = compose({
  fns: [validateData, transformData, saveData],
  args: { strict: true },
});

// Promise detection
if (isPromiseLike(result)) {
  const data = await result;
} else {
  const data = result;
}

Plugin Application Patterns

Modify Pattern

Used for transforming values through a chain of plugins:

// Synchronous modification
const result = pluginManager.applyPlugins({
  key: "modifyConfig",
  type: ApplyPluginsType.modify,
  initialValue: baseConfig,
});

// Asynchronous modification
const result = await pluginManager.applyPlugins({
  key: "modifyConfig",
  type: ApplyPluginsType.modify,
  initialValue: baseConfig,
  async: true,
});

Event Pattern

Used for triggering side effects without return values:

// Event execution (all hooks called)
await pluginManager.applyPlugins({
  key: "onBuildComplete",
  type: ApplyPluginsType.event,
  args: { buildStats },
});

Compose Pattern

Used for function composition and middleware patterns:

// Function composition
const composedFn = pluginManager.applyPlugins({
  key: "middleware",
  type: ApplyPluginsType.compose,
  initialValue: baseFn,
});

// Execute composed function
const result = composedFn();

Type Definitions

// Plugin application types
enum ApplyPluginsType {
  compose = "compose",
  modify = "modify",
  event = "event"
}

// Plugin definition interface
interface IPlugin {
  path?: string;
  apply: Record<string, any>;
}

// Plugin manager configuration
interface PluginManagerOpts {
  validKeys: string[];
}

// Plugin application options
interface ApplyPluginsOpts {
  key: string;
  type: ApplyPluginsType;
  initialValue?: any;
  args?: object;
  async?: boolean;
}

// Plugin manager creation options
interface CreatePluginManagerOpts {
  validKeys: string[];
  plugins: IPlugin[];
}

// Function composition options
interface ComposeOpts {
  fns: Function[];
  args?: any;
}

Install with Tessl CLI

npx tessl i tessl/npm-umi

docs

cli-service.md

configuration.md

index.md

plugin-system.md

testing.md

tile.json