CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-unplugin-vue-components

Vue component auto-importing plugin for multiple build tools including Vite, Webpack, Rollup, and esbuild

Pending
Overview
Eval results
Files

component-resolution.mddocs/

Component Resolution

Built-in component discovery from directories and extensible resolver system for UI libraries, with support for custom resolution logic and namespace management.

Capabilities

Component Discovery

Automatic component discovery from configured directories with flexible naming and namespace support.

/**
 * Component discovery configuration
 */
interface ComponentDiscoveryOptions {
  /** Directories to search for components */
  dirs?: string | string[];
  /** File extensions to consider as components */
  extensions?: string | string[];
  /** Search subdirectories recursively */
  deep?: boolean;
  /** Use directory structure as component namespaces */
  directoryAsNamespace?: boolean;
  /** Component name prefix */
  prefix?: string;
}

Usage Examples:

// Basic directory discovery
Components({
  dirs: ["src/components"],
  extensions: ["vue", "tsx"],
  deep: true,
});

// With namespacing
Components({
  dirs: ["src/components"],
  directoryAsNamespace: true,
  // src/components/form/Input.vue becomes <FormInput>
});

Custom Resolvers

Extensible resolver system for custom component resolution logic, supporting both function-based and object-based resolvers.

/**
 * Function-based component resolver
 * @param name - Component name to resolve
 * @returns Component resolution result
 */
type ComponentResolverFunction = (name: string) => ComponentResolveResult;

/**
 * Object-based component resolver with type specification
 */
interface ComponentResolverObject {
  /** Type of items this resolver handles */
  type: "component" | "directive";
  /** Resolution function */
  resolve: ComponentResolverFunction;
}

/**
 * Union type for all resolver types
 */
type ComponentResolver = ComponentResolverFunction | ComponentResolverObject;

/**
 * Result of component resolution
 */
type ComponentResolveResult = Awaitable<string | ComponentInfo | null | undefined | void>;

/**
 * Component information returned by resolvers
 */
interface ComponentInfo {
  /** Import alias name */
  as?: string;
  /** Component name */
  name?: string;
  /** Import path or module name */
  from: string;
  /** Side effect imports (CSS, etc.) */
  sideEffects?: SideEffectsInfo;
}

type SideEffectsInfo = (ImportInfo | string)[] | ImportInfo | string | undefined;

interface ImportInfo {
  as?: string;
  name?: string;
  from: string;
}

Usage Examples:

// Function-based resolver
Components({
  resolvers: [
    (name: string) => {
      if (name.startsWith("My")) {
        return {
          name,
          from: `@/components/${name}.vue`,
        };
      }
    },
  ],
});

// Object-based resolver with type
Components({
  resolvers: [
    {
      type: "component",
      resolve: (name: string) => {
        if (name.match(/^V[A-Z]/)) {
          return {
            name,
            from: "vuetify/components",
            sideEffects: "vuetify/styles",
          };
        }
      },
    },
  ],
});

Resolver Chaining

Multiple resolvers can be configured and will be called in order until one returns a result.

/**
 * Multiple resolvers are processed in order
 */
interface ResolverChainOptions {
  resolvers?: ComponentResolver[];
}

Usage Examples:

Components({
  resolvers: [
    // First try UI library resolvers
    ElementPlusResolver(),
    AntDesignVueResolver(),
    
    // Then custom business logic
    (name: string) => {
      if (name.startsWith("App")) {
        return { name, from: `@/components/app/${name}.vue` };
      }
    },
    
    // Finally fallback resolver
    (name: string) => {
      return { name, from: `@/components/fallback/${name}.vue` };
    },
  ],
});

Advanced Resolution Features

Advanced features for complex resolution scenarios including conditional resolution and dynamic imports.

/**
 * Advanced resolver with conditional logic
 */
interface AdvancedResolverResult {
  /** Component name override */
  name?: string;
  /** Import source */
  from: string;
  /** Import alias */
  as?: string;
  /** Side effects to import */
  sideEffects?: SideEffectsInfo;
}

Usage Examples:

// Conditional resolution based on environment
Components({
  resolvers: [
    (name: string) => {
      // Use different components for different environments
      if (name === "DataGrid") {
        const isDev = process.env.NODE_ENV === "development";
        return {
          name,
          from: isDev ? "@/components/dev/DataGrid.vue" : "@/components/prod/DataGrid.vue",
        };
      }
    },
  ],
});

// Dynamic resolution with side effects
Components({
  resolvers: [
    (name: string) => {
      if (name.startsWith("Chart")) {
        return {
          name,
          from: "chart-library",
          sideEffects: [
            "chart-library/styles/index.css",
            { from: "chart-library/themes", name: "defaultTheme" },
          ],
        };
      }
    },
  ],
});

Resolution Context

Access to resolution context for advanced use cases.

/**
 * Extended resolver function with context
 */
type ContextualResolverFunction = (
  name: string,
  context?: ResolutionContext
) => ComponentResolveResult;

interface ResolutionContext {
  /** File path where component is being used */
  filename?: string;
  /** Additional context information */
  [key: string]: any;
}

Usage Examples:

// Context-aware resolution
Components({
  resolvers: [
    (name: string, context?: ResolutionContext) => {
      if (context?.filename?.includes("/admin/")) {
        // Use admin-specific components
        return { name, from: `@/components/admin/${name}.vue` };
      }
      return { name, from: `@/components/public/${name}.vue` };
    },
  ],
});

Built-in Utilities

Utility functions commonly used in custom resolvers.

/**
 * String case conversion utilities
 */
function camelCase(str: string): string;
function kebabCase(str: string): string;
function pascalCase(str: string): string;

Usage Examples:

import { camelCase, kebabCase, pascalCase } from "unplugin-vue-components";

Components({
  resolvers: [
    (name: string) => {
      // Convert PascalCase component name to kebab-case file name
      const fileName = kebabCase(name);
      return {
        name,
        from: `@/components/${fileName}.vue`,
      };
    },
  ],
});

Component Name Patterns

Common patterns for component name resolution and transformation.

Usage Examples:

// Prefix-based resolution
Components({
  resolvers: [
    (name: string) => {
      // Handle prefixed components: AppButton -> app/Button.vue
      const match = name.match(/^App(.+)$/);
      if (match) {
        return {
          name,
          from: `@/components/app/${match[1]}.vue`,
        };
      }
    },
  ],
});

// Namespace-based resolution
Components({
  resolvers: [
    (name: string) => {
      // Handle namespaced components: FormInput -> form/Input.vue
      const parts = name.match(/^([A-Z][a-z]+)([A-Z].+)$/);
      if (parts) {
        const [, namespace, component] = parts;
        return {
          name,
          from: `@/components/${namespace.toLowerCase()}/${component}.vue`,
        };
      }
    },
  ],
});

Error Handling

Proper error handling in custom resolvers.

Usage Examples:

Components({
  resolvers: [
    (name: string) => {
      try {
        // Custom resolution logic that might fail
        if (name.startsWith("External")) {
          const moduleName = name.replace("External", "").toLowerCase();
          // Validate module exists
          require.resolve(`external-components/${moduleName}`);
          return {
            name,
            from: `external-components/${moduleName}`,
          };
        }
      } catch (error) {
        // Silently fail - let other resolvers handle it
        return null;
      }
    },
  ],
});

Install with Tessl CLI

npx tessl i tessl/npm-unplugin-vue-components

docs

component-resolution.md

index.md

nuxt-integration.md

plugin-configuration.md

typescript-integration.md

ui-library-resolvers.md

tile.json