or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-commands.mddependency-management.mdindex.mdmodule-discovery.mdplatform-support.mdreact-native-integration.md
tile.json

dependency-management.mddocs/

Dependency Management

Advanced dependency resolution system with caching, workspace support, and duplicate detection for efficient module management in React Native and Expo projects.

Capabilities

Cached Dependencies Linker

Main interface for cached dependency operations with platform-specific configuration loading.

/**
 * Create a cached dependencies linker for efficient dependency management
 * @param params - Configuration parameters including project root
 * @returns CachedDependenciesLinker instance
 */
function makeCachedDependenciesLinker(params: {
  projectRoot: string;
}): CachedDependenciesLinker;

interface CachedDependenciesLinker {
  /** Get platform-specific search options and exclusions */
  getOptionsForPlatform(platform: SupportedPlatform): Promise<CachedDependenciesSearchOptions>;
  /** Load React Native project configuration */
  loadReactNativeProjectConfig(): Promise<RNConfigReactNativeProjectConfig | null>;
  /** Scan dependencies from React Native project config */
  scanDependenciesFromRNProjectConfig(): Promise<ResolutionResult>;
  /** Scan dependencies recursively from project */
  scanDependenciesRecursively(): Promise<ResolutionResult>;
  /** Scan dependencies in specific search path */
  scanDependenciesInSearchPath(searchPath: string): Promise<ResolutionResult>;
}

interface CachedDependenciesSearchOptions {
  excludeNames: Set<string>;
  searchPaths: string[];
}

Usage Examples:

import { makeCachedDependenciesLinker } from "expo-modules-autolinking";

// Create dependency linker
const linker = makeCachedDependenciesLinker({
  projectRoot: "/path/to/project"
});

// Get platform-specific options
const iosOptions = await linker.getOptionsForPlatform("ios");
console.log("iOS search paths:", iosOptions.searchPaths);
console.log("iOS exclusions:", Array.from(iosOptions.excludeNames));

// Scan dependencies recursively
const dependencies = await linker.scanDependenciesRecursively();
console.log("Found dependencies:", Object.keys(dependencies));

Dependency Resolution Functions

Core functions for scanning and resolving dependencies from various sources.

/**
 * Scan dependencies recursively from project root
 * @param rawPath - Root directory path to scan from
 * @param options - Resolution configuration options
 * @returns Promise resolving to dependency resolution results
 */
function scanDependenciesRecursively(
  rawPath: string,
  options?: {
    shouldIncludeDependency?: (name: string) => boolean;
    limitDepth?: number;
  }
): Promise<ResolutionResult>;

/**
 * Scan dependencies in specific search path
 * @param rawPath - Directory path to scan
 * @param options - Resolution configuration options
 * @returns Promise resolving to dependency resolution results
 */
function scanDependenciesInSearchPath(
  rawPath: string,
  options?: {
    shouldIncludeDependency?: (name: string) => boolean;
  }
): Promise<ResolutionResult>;

/**
 * Scan dependencies from React Native project configuration
 * @param rawPath - Project root path
 * @param projectConfig - React Native project configuration (can be null)
 * @param options - Resolution configuration options
 * @returns Promise resolving to dependency resolution results
 */
function scanDependenciesFromRNProjectConfig(
  rawPath: string,
  projectConfig: RNConfigReactNativeProjectConfig | null,
  options?: {
    shouldIncludeDependency?: (name: string) => boolean;
  }
): Promise<ResolutionResult>;

Usage Examples:

import { 
  scanDependenciesRecursively,
  scanDependenciesInSearchPath,
  scanDependenciesFromRNProjectConfig
} from "expo-modules-autolinking";

// Scan dependencies recursively
const allDeps = await scanDependenciesRecursively("/path/to/project", {
  shouldIncludeDependency: (name) => !name.includes("react-native-vector-icons"),
  limitDepth: 5
});

// Scan specific search path
const customDeps = await scanDependenciesInSearchPath("./custom-modules", {
  shouldIncludeDependency: (name) => !name.startsWith("@types/")
});

// Scan from React Native config
const rnConfig = await loadReactNativeConfig();
const configDeps = await scanDependenciesFromRNProjectConfig(
  "/path/to/project",
  rnConfig,
  {
    shouldIncludeDependency: (name) => true
  }
);

Resolution Utility Functions

Utility functions for processing and merging dependency resolution results.

/**
 * Filter and map resolution results based on criteria
 * @param result - Resolution result to filter
 * @param filterFn - Function to filter dependencies
 * @param mapFn - Function to transform dependency resolutions
 * @returns Filtered and mapped resolution result
 */
function filterMapResolutionResult<T>(
  result: ResolutionResult,
  filterFn: (dep: DependencyResolution) => boolean,
  mapFn: (dep: DependencyResolution) => T
): Record<string, T>;

/**
 * Merge multiple resolution results into single result
 * @param results - Array of resolution results to merge
 * @returns Merged resolution result with conflict resolution
 */
function mergeResolutionResults(
  ...results: ResolutionResult[]
): ResolutionResult;

Usage Examples:

import { 
  filterMapResolutionResult,
  mergeResolutionResults
} from "expo-modules-autolinking";

// Filter to only production dependencies
const prodDeps = filterMapResolutionResult(
  allDependencies,
  (dep) => dep.source !== DependencyResolutionSource.SEARCH_PATH,
  (dep) => ({ name: dep.name, version: dep.version })
);

// Merge results from multiple sources
const mergedDeps = mergeResolutionResults(
  recursiveDeps,
  searchPathDeps,
  rnConfigDeps
);

Platform-Specific Scanning

Functions for scanning Expo module resolutions with platform-specific filtering.

/**
 * Scan dependency resolutions for specific platform
 * @param platform - Target platform for scanning
 * @param projectRoot - Project root directory
 * @param options - Platform-specific scanning options
 * @returns Promise resolving to platform-filtered resolution results
 */
function scanDependencyResolutionsForPlatform(
  platform: SupportedPlatform,
  projectRoot: string,
  options?: PlatformScanOptions
): Promise<ResolutionResult>;

/**
 * Scan Expo module resolutions for specific platform
 * @param platform - Target platform for scanning
 * @param projectRoot - Project root directory
 * @param options - Expo module scanning options
 * @returns Promise resolving to Expo module resolution results
 */
function scanExpoModuleResolutionsForPlatform(
  platform: SupportedPlatform,
  projectRoot: string,
  options?: ExpoModuleScanOptions
): Promise<ResolutionResult>;

Usage Examples:

import { 
  scanDependencyResolutionsForPlatform,
  scanExpoModuleResolutionsForPlatform
} from "expo-modules-autolinking";

// Scan dependencies for iOS platform
const iosDeps = await scanDependencyResolutionsForPlatform("ios", "/path/to/project", {
  excludeDevDependencies: true,
  includeOptionalDependencies: false
});

// Scan only Expo modules for Android
const androidExpoModules = await scanExpoModuleResolutionsForPlatform("android", "/path/to/project");

Dependency Resolution Types

const enum DependencyResolutionSource {
  RECURSIVE_RESOLUTION,
  SEARCH_PATH,
  RN_CLI_LOCAL,
}

interface BaseDependencyResolution {
  name: string;
  version: string;
  path: string;
  originPath: string;
}

interface DependencyResolution extends BaseDependencyResolution {
  source: DependencyResolutionSource;
  duplicates: BaseDependencyResolution[] | null;
  depth: number;
  [prop: string]: unknown;
}

type ResolutionResult = Record<string, DependencyResolution | undefined>;

Advanced Configuration

interface DependencyScanOptions {
  excludeNames?: Set<string>;
  maxDepth?: number;
  includeDevDependencies?: boolean;
  includeOptionalDependencies?: boolean;
}

interface PlatformScanOptions extends DependencyScanOptions {
  platformSpecific?: boolean;
  includeNativeModules?: boolean;
}

interface ExpoModuleScanOptions extends PlatformScanOptions {
  requireExpoModuleConfig?: boolean;
  includeLegacyModules?: boolean;
}

Caching and Performance

The dependency management system includes sophisticated caching mechanisms:

  • Resolution Caching: Cache dependency resolution results to avoid repeated filesystem operations
  • Workspace Support: Efficient handling of monorepo and workspace structures
  • Duplicate Detection: Identify and resolve version conflicts across dependency trees
  • Lazy Loading: Load dependency information only when needed

Caching Example:

import { makeCachedDependenciesLinker } from "expo-modules-autolinking";

// Create linker with caching enabled
const linker = makeCachedDependenciesLinker({
  projectRoot: "/path/to/monorepo",
});

// First scan - builds cache
const initialScan = await linker.scanDependenciesRecursively();

// Subsequent scans use cached results
const cachedScan = await linker.scanDependenciesRecursively();

Error Handling and Validation

The dependency management system provides comprehensive error handling:

try {
  const linker = makeCachedDependenciesLinker({
    projectRoot: "/invalid/path"
  });
  
  const deps = await linker.scanDependenciesRecursively();
} catch (error) {
  if (error instanceof ProjectNotFoundError) {
    console.error("Project root not found:", error.path);
  } else if (error instanceof DependencyResolutionError) {
    console.error("Failed to resolve dependency:", error.packageName);
    console.error("Reason:", error.reason);
  }
}

Integration with Build Systems

The dependency management system integrates seamlessly with native build systems:

  • Gradle Integration: Generate Gradle-compatible dependency lists for Android
  • CocoaPods Integration: Generate Podfile entries for iOS dependencies
  • Metro Integration: Configure Metro bundler with resolved dependencies
  • Webpack Integration: Provide webpack-compatible module resolution