CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-dumi

Documentation generator for React component libraries with live demos, API tables, and theming support

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

plugins.mddocs/

Plugin System

Plugin architecture for extending dumi functionality with custom tech stacks, content tabs, and asset processing through a comprehensive API system.

Capabilities

Tech Stack Registration

Register custom technology stacks for supporting additional frameworks beyond React.

/**
 * Register a new tech stack for parsing and rendering demos
 * @param fn - Function returning tech stack implementation
 */
interface IApi {
  registerTechStack: (fn: () => IDumiTechStack) => void;
}

/**
 * Abstract base class for implementing custom tech stacks
 */
abstract class IDumiTechStack {
  /** Tech stack name (e.g., 'react', 'vue', 'angular') */
  abstract name: string;
  
  /** Runtime options for browser rendering */
  abstract runtimeOpts?: {
    /** Path to component detection function */
    preflightPath?: string;
    /** Path to render/unmount function */
    rendererPath?: string;
    /** Path to runtime compile function */
    compilePath?: string;
    /** Path to runtime plugin */
    pluginPath?: string;
  };
  
  /**
   * Check if language/node is supported by this tech stack
   * @param node - HAST element node
   * @param lang - Code block language
   * @returns Whether this tech stack can handle the code
   */
  abstract isSupported(node: Element, lang: string): boolean;
  
  /**
   * Transform demo source code for compilation
   * @param raw - Raw source code
   * @param opts - Transformation options
   * @returns Transformed code ready for compilation
   */
  abstract transformCode(raw: string, opts: {
    type: 'external' | 'code-block';
    fileAbsPath: string;
  }): string;
  
  /**
   * Generate asset metadata for the demo
   * @param asset - Base asset data
   * @param opts - Generation context
   * @returns Enhanced asset metadata
   */
  abstract generateMetadata?(
    asset: ExampleBlockAsset,
    opts: {
      type: 'external' | 'code-block';
      mdAbsPath: string;
      fileAbsPath?: string;
      entryPointCode?: string;
    }
  ): Promise<ExampleBlockAsset> | ExampleBlockAsset;
  
  /**
   * Generate previewer component props
   * @param props - Base previewer props
   * @param opts - Generation context
   * @returns Enhanced previewer props
   */
  abstract generatePreviewerProps?(
    props: IDumiDemoProps['previewerProps'],
    opts: {
      type: 'external' | 'code-block';
      mdAbsPath: string;
      fileAbsPath?: string;
      entryPointCode?: string;
    }
  ): Promise<IDumiDemoProps['previewerProps']> | IDumiDemoProps['previewerProps'];
  
  /**
   * Transform code using esbuild onLoad callback
   * @param args - esbuild onLoad arguments
   * @returns Transformed code result or null to skip
   */
  abstract onBlockLoad?(args: {
    path: string;
    namespace?: string;
    suffix?: string;
    pluginData?: any;
    entryPointCode: string;
    filename: string;
  }): { content: string; loader: string } | null;
}

Usage:

// Vue.js tech stack implementation
export default (api: IApi) => {
  api.registerTechStack(() => ({
    name: 'vue',
    
    isSupported(node, lang) {
      return ['vue', 'vue3'].includes(lang);
    },
    
    transformCode(raw, { type, fileAbsPath }) {
      // Transform Vue SFC to executable code
      return `
        import { createApp } from 'vue';
        
        const component = ${raw};
        
        export default () => {
          const app = createApp(component);
          return app;
        };
      `;
    },
    
    runtimeOpts: {
      rendererPath: require.resolve('./vue-renderer'),
      compilePath: require.resolve('./vue-compiler'),
    },
  }));
};

Content Tab System

Add custom content tabs for enhanced page functionality.

/**
 * Add a content tab to documentation pages
 * @param fn - Function returning tab configuration
 */
interface IApi {
  addContentTab: (fn: () => IContentTab) => void;
}

interface IContentTab {
  /** Unique tab key and URL query parameter */
  key: string;
  /** Optional unique ID for tab conflicts */
  id?: string;
  /** Route pattern to apply tab (regex) */
  test?: RegExp;
  /** Tab display title */
  title?: string;
  /** Internationalization key for title */
  titleIntlId?: string;
  /** Path to tab React component */
  component: string;
}

Usage:

// Add playground tab for interactive demos
export default (api: IApi) => {
  api.addContentTab(() => ({
    key: 'playground',
    test: /\/components\//,
    title: 'Playground',
    component: require.resolve('./PlaygroundTab'),
  }));
};

// PlaygroundTab.tsx
import React from 'react';
import { useRouteMeta, useLiveDemo } from 'dumi/theme';

export default function PlaygroundTab() {
  const routeMeta = useRouteMeta();
  const { renderDemo } = useLiveDemo();
  
  return (
    <div>
      <h2>Interactive Playground</h2>
      {/* Custom playground implementation */}
    </div>
  );
}

Asset Metadata Management

Modify and access component/demo asset metadata.

/**
 * Modify assets metadata during build process
 * @param fn - Function to transform assets data
 */
interface IApi {
  modifyAssetsMetadata: (fn: (memo: AssetsPackage, args: null) => AssetsPackage) => void;
}

/**
 * Get current assets metadata (available during build)
 * @returns Promise resolving to complete assets package
 */
interface IApi {
  getAssetsMetadata?: () => Promise<AssetsPackage>;
}

interface AssetsPackage {
  /** Package name */
  name: string;
  /** Package version */
  version: string;
  /** Package description */
  description?: string;
  /** Package homepage */
  homepage?: string;
  /** Package keywords */
  keywords?: string[];
  /** Component/function assets */
  assets: {
    /** Atom assets by ID */
    atoms: Record<string, AtomAsset>;
    /** Example assets by ID */
    examples: Record<string, ExampleBlockAsset>;
  };
}

Usage:

// Enhance asset metadata with custom information
export default (api: IApi) => {
  api.modifyAssetsMetadata((assets) => {
    // Add custom package information
    assets.name = 'My Design System';
    assets.homepage = 'https://my-design-system.com';
    
    // Enhance component metadata
    Object.values(assets.assets.atoms).forEach((atom) => {
      if (atom.type === 'COMPONENT') {
        // Add design system category
        atom.category = getComponentCategory(atom.id);
        
        // Add accessibility information
        atom.a11y = getA11yInfo(atom.id);
      }
    });
    
    return assets;
  });
  
  // Access metadata during build
  api.onBuildComplete(async () => {
    const assets = await api.getAssetsMetadata?.();
    
    // Generate additional documentation files
    generateComponentCatalog(assets);
    generateA11yReport(assets);
  });
};

Theme Modification

Modify theme components and configuration.

/**
 * Modify theme data including components, layouts, and locales
 * @param fn - Function to transform theme data
 */
interface IApi {
  modifyTheme: (fn: (memo: IThemeLoadResult, args: null) => IThemeLoadResult) => void;
}

interface IThemeLoadResult {
  /** Built-in components (API, Badge, etc.) */
  builtins: Record<string, string>;
  /** Layout components (DocLayout, etc.) */
  layouts: Record<string, string>;
  /** Slot components (Header, Footer, etc.) */
  slots: Record<string, string>;
  /** Internationalization messages */
  locales: Record<string, {
    messages: Record<string, string>;
  }>;
  /** Global style files */
  globalStyles: string[];
  /** Custom theme configuration */
  [key: string]: any;
}

Usage:

// Customize theme with additional components and styling
export default (api: IApi) => {
  api.modifyTheme((memo) => {
    // Add custom built-in components
    memo.builtins.CustomAPI = require.resolve('./components/CustomAPI');
    memo.builtins.DesignTokens = require.resolve('./components/DesignTokens');
    
    // Override default slots
    memo.slots.Header = require.resolve('./components/CustomHeader');
    memo.slots.Footer = require.resolve('./components/CustomFooter');
    
    // Add custom internationalization
    memo.locales.en.messages.customWelcome = 'Welcome to our design system';
    memo.locales.zh.messages.customWelcome = '欢迎使用我们的设计系统';
    
    // Add global styles
    memo.globalStyles.push(require.resolve('./styles/custom.less'));
    
    return memo;
  });
};

Plugin Development Utilities

Utilities for building robust plugins.

/**
 * Plugin API interface extending Umi's plugin system
 */
interface IApi extends IUmiApi {
  /** Dumi-specific configuration */
  config: IDumiConfig & { [key: string]: any };
  /** User configuration */
  userConfig: IDumiUserConfig;
  /** Enhanced service with theme and parser data */
  service: IUmiApi['service'] & {
    themeData: IThemeLoadResult;
    atomParser: IAtomAssetsParser;
  };
}

/**
 * Language metadata parser for API documentation
 */
interface ILanguageMetaParser {
  /** Language identifier */
  language: string;
  /** Parse component/function metadata */
  parse(code: string, options: {
    filename: string;
    entryFile?: string;
  }): Promise<AtomAsset[]>;
}

/**
 * Options for creating API parsers
 */
interface IBaseApiParserOptions {
  /** Entry file for parsing */
  entryFile?: string;
  /** Custom resolver function */
  resolveFilter?: (args: {
    id: string;
    type: 'COMPONENT' | 'FUNCTION';
  }) => boolean;
}

Usage:

// Advanced plugin with custom API parser
export default (api: IApi) => {
  api.describe({ key: 'custom-plugin' });
  
  // Register custom methods
  api.registerMethod({ name: 'addCustomTab' });
  api.registerMethod({ name: 'enhanceMetadata' });
  
  // Hook into lifecycle events
  api.onStart(() => {
    console.log('Plugin starting...');
  });
  
  api.onBuildComplete(() => {
    console.log('Build completed, running custom tasks...');
  });
  
  // Access service data
  const { themeData, atomParser } = api.service;
  
  // Custom parsing logic
  api.modifyConfig((memo) => {
    memo.resolve.entryFile = './src/custom-entry.ts';
    return memo;
  });
};

Plugin Examples

Design System Plugin

// Complete design system enhancement plugin
export default (api: IApi) => {
  api.describe({ key: 'design-system-plugin' });
  
  // Add design tokens tab
  api.addContentTab(() => ({
    key: 'tokens',
    title: 'Design Tokens',
    component: require.resolve('./DesignTokensTab'),
  }));
  
  // Enhance theme with design system components
  api.modifyTheme((memo) => {
    memo.builtins.TokenTable = require.resolve('./TokenTable');
    memo.builtins.ColorPalette = require.resolve('./ColorPalette');
    memo.builtins.Typography = require.resolve('./Typography');
    return memo;
  });
  
  // Add design system metadata
  api.modifyAssetsMetadata((assets) => {
    assets.designSystem = {
      tokens: loadDesignTokens(),
      guidelines: loadDesignGuidelines(),
    };
    return assets;
  });
};

Multi-framework Support Plugin

// Plugin supporting React, Vue, and Angular
export default (api: IApi) => {
  // Register Vue tech stack
  api.registerTechStack(() => new VueTechStack());
  
  // Register Angular tech stack  
  api.registerTechStack(() => new AngularTechStack());
  
  // Add framework selector tab
  api.addContentTab(() => ({
    key: 'frameworks',
    title: 'Frameworks',
    component: require.resolve('./FrameworkSelector'),
  }));
};

class VueTechStack extends IDumiTechStack {
  name = 'vue';
  
  isSupported(node, lang) {
    return lang === 'vue';
  }
  
  transformCode(raw, opts) {
    return compileVueComponent(raw, opts);
  }
}

Analytics Plugin

// Plugin for tracking component usage and demos
export default (api: IApi) => {
  api.describe({ key: 'analytics-plugin' });
  
  // Track component views
  api.modifyTheme((memo) => {
    memo.builtins.TrackingPreviewer = require.resolve('./TrackingPreviewer');
    return memo;
  });
  
  // Generate usage reports
  api.onBuildComplete(async () => {
    const assets = await api.getAssetsMetadata?.();
    generateUsageReport(assets);
  });
};

Install with Tessl CLI

npx tessl i tessl/npm-dumi

docs

cli.md

configuration.md

index.md

plugins.md

theme-api.md

utilities.md

tile.json