CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ice--app

A universal framework based on React.js that provides scripts and configuration for web development with zero-config support for ES6+, TypeScript, routing, state management, and multi-platform deployment.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

analysis.mddocs/

Code Analysis

Ice.js provides powerful static analysis utilities for dependency scanning, import analysis, and export discovery in JavaScript/TypeScript projects. These tools enable build optimization, dependency management, and codebase understanding.

Capabilities

Import Analysis

Analyze module imports in source files with support for aliases and relative imports.

/**
 * Analyze module imports in source files
 * @param files - Array of file paths to analyze
 * @param options - Analysis configuration options
 * @returns Promise resolving to Set of imported modules or false on error
 */
function analyzeImports(files: string[], options: AnalyzeOptions): Promise<Set<string> | false>;

interface AnalyzeOptions {
  /** Number of parallel analysis operations (default: 10) */
  parallel?: number;
  /** Whether to analyze relative imports (default: false) */
  analyzeRelativeImport?: boolean;
  /** Module path aliases for import resolution */
  alias?: Record<string, string>;
}

Usage Examples:

import { analyzeImports } from "@ice/app/analyze";

// Basic import analysis
const sourceFiles = [
  'src/index.ts',
  'src/components/App.tsx',
  'src/utils/helpers.ts'
];

const imports = await analyzeImports(sourceFiles, {
  parallel: 5,
  analyzeRelativeImport: true,
  alias: {
    '@': './src',
    '@components': './src/components'
  }
});

if (imports) {
  console.log('Discovered imports:', Array.from(imports));
  // Output: ['react', 'react-dom', 'lodash', './utils/constants', '@/components/Button']
}

// Advanced analysis with custom options
const advancedImports = await analyzeImports(['src/**/*.{ts,tsx}'], {
  parallel: 20,
  analyzeRelativeImport: false, // Skip relative imports
  alias: {
    '@': './src',
    '@lib': './src/lib',
    '@components': './src/components',
    '@utils': './src/utils'
  }
});

Dependency Scanning

Scan entry points and discover all dependencies including dynamic imports and conditional requires.

/**
 * Scan entry points and discover dependencies
 * @param entries - Array of entry point file paths
 * @param options - Scan configuration options
 * @returns Promise resolving to dependency scan data
 */
function scanImports(entries: string[], options?: ScanOptions): Promise<Record<string, DepScanData>>;

interface ScanOptions {
  /** Project root directory */
  rootDir?: string;
  /** Module path aliases */
  alias?: Record<string, string>;
  /** Existing dependency imports to merge with */
  depImports?: Record<string, DepScanData>;
  /** ESBuild plugins for custom file processing */
  plugins?: Plugin[];
  /** Patterns to exclude from scanning */
  exclude?: string[];
  /** Files to ignore during scanning */
  ignores?: string[];
}

interface DepScanData {
  /** Imported module specifiers */
  imports: Set<string>;
  /** Dynamic import specifiers */
  dynamicImports: Set<string>;
  /** Export names from the module */
  exports: Set<string>;
  /** File dependencies */
  deps: Set<string>;
  /** Whether the module has side effects */
  hasSideEffects: boolean;
}

Usage Examples:

import { scanImports } from "@ice/app/analyze";

// Basic dependency scanning
const entryPoints = ['src/index.ts', 'src/main.tsx'];

const dependencies = await scanImports(entryPoints, {
  rootDir: process.cwd(),
  alias: {
    '@': './src',
    '@components': './src/components'
  },
  exclude: ['**/*.test.*', '**/*.spec.*'],
  ignores: ['node_modules', 'dist']
});

// Process scan results
Object.entries(dependencies).forEach(([file, data]) => {
  console.log(`File: ${file}`);
  console.log('  Imports:', Array.from(data.imports));
  console.log('  Dynamic imports:', Array.from(data.dynamicImports));
  console.log('  Exports:', Array.from(data.exports));
  console.log('  Has side effects:', data.hasSideEffects);
});

// Advanced scanning with custom plugins
import { esbuild } from '@ice/bundles';

const advancedDeps = await scanImports(['src/index.ts'], {
  rootDir: '/path/to/project',
  plugins: [
    {
      name: 'custom-loader',
      setup(build) {
        build.onLoad({ filter: /\.custom$/ }, (args) => {
          // Custom file processing logic
        });
      }
    }
  ],
  exclude: ['**/*.md', '**/*.json']
});

Export Analysis

Analyze file exports to understand module interfaces and public APIs.

/**
 * Get file export information
 * @param options - File analysis options
 * @returns Promise resolving to array of export names
 */
function getFileExports(options: FileExportOptions): Promise<string[]>;

interface FileExportOptions {
  /** File path (relative or absolute) */
  file: string;
  /** Project root directory */
  rootDir: string;
}

Usage Examples:

import { getFileExports } from "@ice/app/analyze";

// Analyze exports from a specific file
const exports = await getFileExports({
  file: 'src/utils/helpers.ts',
  rootDir: process.cwd()
});

console.log('Exported functions:', exports);
// Output: ['formatDate', 'validateEmail', 'debounce', 'throttle']

// Analyze exports from multiple files
const files = [
  'src/components/Button.tsx',
  'src/components/Input.tsx', 
  'src/hooks/useLocalStorage.ts'
];

const allExports = await Promise.all(
  files.map(file => getFileExports({
    file,
    rootDir: process.cwd()
  }))
);

files.forEach((file, index) => {
  console.log(`${file}: [${allExports[index].join(', ')}]`);
});

Module Resolution

Resolve module IDs with alias support for import path resolution.

/**
 * Resolve module ID with alias support
 * @param id - Module identifier to resolve
 * @param alias - Alias configuration with empty values for exclusion
 * @returns Resolved module path or false if excluded
 */
function resolveId(id: string, alias: AliasWithEmpty): string | false;

/**
 * Get absolute import path with alias resolution
 * @param id - Module identifier
 * @param importer - File path of the importing module
 * @param alias - Alias configuration
 * @returns Resolved absolute import path
 */
function getImportPath(id: string, importer: string, alias: Alias): string;

type Alias = Record<string, string>;
type AliasWithEmpty = Record<string, string | false>;

Usage Examples:

import { resolveId, getImportPath } from "@ice/app/analyze";

// Basic module resolution with aliases
const aliasConfig = {
  '@': './src',
  '@components': './src/components',
  '@utils': './src/utils',
  'excluded-module$': false // Exclude this module
};

// Resolve various import paths
console.log(resolveId('@/components/Button', aliasConfig));
// Output: './src/components/Button'

console.log(resolveId('@utils/helpers', aliasConfig));  
// Output: './src/utils/helpers'

console.log(resolveId('excluded-module', aliasConfig));
// Output: false (excluded)

// Get absolute import paths
const absolutePath = getImportPath(
  '@/components/Button',
  '/project/src/pages/Home.tsx',
  {
    '@': './src',
    '@components': './src/components'
  }
);
console.log(absolutePath);
// Output: '/project/src/components/Button'

Build Optimization Analysis

Use analysis results for build optimization and bundle splitting.

/**
 * Analyze codebase for build optimization opportunities
 */
interface OptimizationAnalysis {
  /** Unused dependencies that can be removed */
  unusedDependencies: string[];
  /** Large dependencies that should be code-split */
  largeDependencies: Array<{ name: string; size: number }>;
  /** Circular dependencies that need resolution */
  circularDependencies: string[][];
  /** Barrel files that can be optimized */
  barrelFiles: string[];
}

Usage Examples:

import { analyzeImports, scanImports, getFileExports } from "@ice/app/analyze";
import fs from 'fs';
import path from 'path';

// Comprehensive analysis for optimization
async function analyzeForOptimization(rootDir: string): Promise<OptimizationAnalysis> {
  // Get all source files
  const sourceFiles = getAllSourceFiles(rootDir);
  
  // Analyze imports
  const imports = await analyzeImports(sourceFiles, {
    parallel: 10,
    analyzeRelativeImport: true,
    alias: {
      '@': './src'  
    }
  });

  // Scan dependencies
  const deps = await scanImports(['src/index.ts'], {
    rootDir,
    exclude: ['**/*.test.*']
  });

  // Find optimization opportunities
  const analysis: OptimizationAnalysis = {
    unusedDependencies: findUnusedDependencies(imports, deps),
    largeDependencies: findLargeDependencies(imports),
    circularDependencies: findCircularDependencies(deps),
    barrelFiles: findBarrelFiles(sourceFiles)
  };

  return analysis;
}

function getAllSourceFiles(rootDir: string): string[] {
  // Implementation to recursively find all source files
  // This is a simplified example
  const glob = require('fast-glob');
  return glob.sync('src/**/*.{ts,tsx,js,jsx}', { cwd: rootDir });
}

function findUnusedDependencies(imports: Set<string>, deps: any): string[] {
  // Logic to identify unused dependencies
  return [];
}

function findLargeDependencies(imports: Set<string>): Array<{ name: string; size: number }> {
  // Logic to identify large dependencies
  return [];
}

function findCircularDependencies(deps: any): string[][] {
  // Logic to detect circular dependencies
  return [];
}

function findBarrelFiles(files: string[]): string[] {
  // Logic to identify barrel files (index.ts files that only re-export)
  return files.filter(file => path.basename(file) === 'index.ts');
}

Integration with Build Pipeline

Integrate analysis tools with custom build pipelines.

/**
 * Integration example with build pipeline
 */
interface BuildAnalysisOptions {
  rootDir: string;
  entryPoints: string[];
  alias: Record<string, string>;
  outputPath: string;
}

Usage Examples:

import { analyzeImports, scanImports } from "@ice/app/analyze";
import fs from 'fs-extra';

class BuildAnalyzer {
  private options: BuildAnalysisOptions;
  
  constructor(options: BuildAnalysisOptions) {
    this.options = options;
  }

  async analyze(): Promise<void> {
    const { rootDir, entryPoints, alias, outputPath } = this.options;

    // Perform comprehensive analysis
    const [imports, dependencies] = await Promise.all([
      this.analyzeAllImports(),
      this.scanAllDependencies()
    ]);

    // Generate analysis report
    const report = {
      timestamp: new Date().toISOString(),
      rootDir,
      entryPoints,
      imports: Array.from(imports || []),
      dependencies: this.processDependencies(dependencies),
      statistics: this.calculateStatistics(imports, dependencies)
    };

    // Save report
    await fs.writeJson(path.join(outputPath, 'analysis-report.json'), report, {
      spaces: 2
    });

    console.log(`Analysis complete. Report saved to ${outputPath}/analysis-report.json`);
  }

  private async analyzeAllImports(): Promise<Set<string> | false> {
    const sourceFiles = await this.getAllSourceFiles();
    
    return analyzeImports(sourceFiles, {
      parallel: 15,
      analyzeRelativeImport: true,
      alias: this.options.alias
    });
  }

  private async scanAllDependencies(): Promise<Record<string, DepScanData>> {
    return scanImports(this.options.entryPoints, {
      rootDir: this.options.rootDir,
      alias: this.options.alias,
      exclude: ['**/*.test.*', '**/*.spec.*', '**/*.stories.*']
    });
  }

  private async getAllSourceFiles(): Promise<string[]> {
    const glob = require('fast-glob');
    return glob.sync('src/**/*.{ts,tsx,js,jsx}', { 
      cwd: this.options.rootDir 
    });
  }

  private processDependencies(deps: Record<string, DepScanData>) {
    return Object.entries(deps).map(([file, data]) => ({
      file,
      imports: Array.from(data.imports),
      dynamicImports: Array.from(data.dynamicImports),
      exports: Array.from(data.exports),
      hasSideEffects: data.hasSideEffects
    }));
  }

  private calculateStatistics(imports: Set<string> | false, deps: Record<string, DepScanData>) {
    return {
      totalImports: imports ? imports.size : 0,
      totalFiles: Object.keys(deps).length,
      averageImportsPerFile: imports && Object.keys(deps).length > 0 
        ? imports.size / Object.keys(deps).length 
        : 0
    };
  }
}

// Usage
const analyzer = new BuildAnalyzer({
  rootDir: process.cwd(),
  entryPoints: ['src/index.ts', 'src/main.tsx'],
  alias: {
    '@': './src',
    '@components': './src/components',
    '@utils': './src/utils'
  },
  outputPath: './analysis'
});

await analyzer.analyze();

These analysis tools provide deep insights into codebase structure, dependencies, and optimization opportunities, enabling data-driven build optimization and better understanding of project architecture.

docs

analysis.md

cli.md

configuration.md

index.md

logging.md

service.md

testing.md

types.md

tile.json