or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

formatters.mdindex.mdissues-filtering.mdplugin-configuration.mdplugin-hooks.mdtypescript-configuration.md
tile.json

plugin-hooks.mddocs/

Plugin Hooks

Extensible hook system for intercepting and customizing type checking lifecycle events. The plugin provides a comprehensive set of hooks using webpack's tapable library, allowing other plugins and tools to integrate with the type checking process.

Capabilities

Plugin Hooks Interface

Complete set of lifecycle hooks for the type checking process.

/**
 * Plugin hooks for extensibility and lifecycle management
 */
interface ForkTsCheckerWebpackPluginHooks {
  /**
   * Called before type checking starts
   * Async waterfall hook that can modify the files change and compilation
   */
  start: AsyncSeriesWaterfallHook<[FilesChange, webpack.Compilation]>;
  
  /**
   * Called while waiting for type checking to complete
   * Sync hook for status updates and progress reporting
   */
  waiting: SyncHook<[webpack.Compilation]>;
  
  /**
   * Called when type checking is canceled
   * Sync hook for cleanup and status updates
   */
  canceled: SyncHook<[webpack.Compilation]>;
  
  /**
   * Called when an error occurs during type checking
   * Sync hook for error handling and reporting
   */
  error: SyncHook<[unknown, webpack.Compilation]>;
  
  /**
   * Called when type checking issues are found
   * Sync waterfall hook that can modify the issues array
   */
  issues: SyncWaterfallHook<[Issue[], webpack.Compilation | undefined], void>;
}

Hook Accessor Function

Function to access plugin hooks for a given webpack compiler.

/**
 * Get plugin hooks for a webpack compiler
 * @param compiler - Webpack compiler or multi-compiler instance
 * @returns Plugin hooks object for tapping into lifecycle events
 */
function getPluginHooks(
  compiler: webpack.Compiler | webpack.MultiCompiler
): ForkTsCheckerWebpackPluginHooks;

Hook Usage Examples

Start Hook

Intercept and modify the type checking start process.

import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';

// In another webpack plugin
class MyPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    // Async hook - can modify files and compilation
    hooks.start.tapPromise('MyPlugin', async (change, compilation) => {
      console.log('Type checking starting...');
      console.log('Changed files:', change.changedFiles);
      console.log('Deleted files:', change.deletedFiles);
      
      // Can modify the change object
      const modifiedChange = {
        ...change,
        changedFiles: change.changedFiles?.filter(file => !file.includes('.test.'))
      };
      
      return [modifiedChange, compilation];
    });
  }
}

Waiting Hook

Monitor type checking progress and provide user feedback.

// Progress reporting plugin
class TypeCheckProgressPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.waiting.tap('TypeCheckProgressPlugin', (compilation) => {
      console.log('⏳ Type checking in progress...');
      
      // Could integrate with webpack's ProgressPlugin
      const logger = compilation.getLogger('TypeCheckProgressPlugin');
      logger.info('TypeScript type checking is running');
    });
  }
}

Canceled Hook

Handle type checking cancellation events.

class TypeCheckCancelPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.canceled.tap('TypeCheckCancelPlugin', (compilation) => {
      console.log('❌ Type checking was canceled');
      
      // Cleanup or logging logic
      const logger = compilation.getLogger('TypeCheckCancelPlugin');
      logger.warn('Type checking process was canceled');
    });
  }
}

Error Hook

Handle type checking errors and failures.

class TypeCheckErrorPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.error.tap('TypeCheckErrorPlugin', (error, compilation) => {
      console.error('πŸ’₯ Type checking error:', error);
      
      // Send to error reporting service
      if (process.env.NODE_ENV === 'production') {
        this.reportError(error, compilation);
      }
      
      // Add compilation error
      compilation.errors.push(new Error(`Type checking failed: ${error}`));
    });
  }
  
  reportError(error, compilation) {
    // Integration with error reporting services
    // e.g., Sentry, Bugsnag, etc.
  }
}

Issues Hook

Intercept and modify type checking issues.

class IssueFilterPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    // Sync waterfall - can modify issues array
    hooks.issues.tap('IssueFilterPlugin', (issues, compilation) => {
      console.log(`πŸ“ Found ${issues.length} type checking issues`);
      
      // Filter issues based on custom logic
      const filteredIssues = issues.filter(issue => {
        // Example: Ignore issues in test files during development
        if (process.env.NODE_ENV === 'development' && issue.file?.includes('.test.')) {
          return false;
        }
        
        // Example: Convert specific warnings to errors
        if (issue.code === 'TS7006' && process.env.STRICT_MODE === 'true') {
          issue.severity = 'error';
        }
        
        return true;
      });
      
      // Log issue summary
      const errors = filteredIssues.filter(i => i.severity === 'error').length;
      const warnings = filteredIssues.filter(i => i.severity === 'warning').length;
      console.log(`πŸ“Š Summary: ${errors} errors, ${warnings} warnings`);
      
      return filteredIssues;
    });
  }
}

Advanced Hook Patterns

Issue Statistics Plugin

Collect and report type checking statistics.

class TypeCheckStatsPlugin {
  private stats = {
    totalRuns: 0,
    totalIssues: 0,
    errorCount: 0,
    warningCount: 0,
    cancelCount: 0
  };
  
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.start.tapPromise('TypeCheckStatsPlugin', async (change, compilation) => {
      this.stats.totalRuns++;
      return [change, compilation];
    });
    
    hooks.issues.tap('TypeCheckStatsPlugin', (issues) => {
      this.stats.totalIssues += issues.length;
      this.stats.errorCount += issues.filter(i => i.severity === 'error').length;
      this.stats.warningCount += issues.filter(i => i.severity === 'warning').length;
      return issues;
    });
    
    hooks.canceled.tap('TypeCheckStatsPlugin', () => {
      this.stats.cancelCount++;
    });
    
    // Report stats on webpack done
    compiler.hooks.done.tap('TypeCheckStatsPlugin', () => {
      console.log('πŸ“ˆ Type Check Statistics:', this.stats);
    });
  }
}

Issue Persistence Plugin

Save issues to file for external processing.

import fs from 'fs/promises';

class IssuePersistencePlugin {
  constructor(private outputPath: string) {}
  
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.issues.tap('IssuePersistencePlugin', async (issues) => {
      const issueData = {
        timestamp: new Date().toISOString(),
        issues: issues.map(issue => ({
          severity: issue.severity,
          code: issue.code,
          message: issue.message,
          file: issue.file,
          location: issue.location
        }))
      };
      
      try {
        await fs.writeFile(this.outputPath, JSON.stringify(issueData, null, 2));
        console.log(`πŸ’Ύ Saved ${issues.length} issues to ${this.outputPath}`);
      } catch (error) {
        console.error('Failed to save issues:', error);
      }
      
      return issues;
    });
  }
}

Integration with Development Tools

Hook integration with development servers and IDEs.

class DevToolsIntegrationPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.issues.tap('DevToolsIntegrationPlugin', (issues) => {
      // Send issues to development server for browser display
      if (compiler.options.devServer) {
        this.sendToBrowser(issues);
      }
      
      // Send to IDE via language server protocol
      if (process.env.IDE_INTEGRATION) {
        this.sendToIDE(issues);
      }
      
      return issues;
    });
  }
  
  private sendToBrowser(issues: Issue[]) {
    // WebSocket integration with dev server overlay
    // Display issues in browser console or overlay
  }
  
  private sendToIDE(issues: Issue[]) {
    // Language Server Protocol integration
    // Send diagnostics to connected IDE
  }
}

Multi-Compiler Support

Hooks automatically support webpack multi-compiler setups.

// The plugin automatically forwards hooks from child compilers to parent
const config = {
  // Multi-compiler setup
  mode: 'development',
  entry: {
    app: './src/app.ts',
    worker: './src/worker.ts'
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin(),
    new MyHookPlugin() // Will receive hooks from both compilers
  ]
};

class MyHookPlugin {
  apply(compiler) {
    // This will work for both single and multi-compiler setups
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
    
    hooks.issues.tap('MyHookPlugin', (issues) => {
      // Handle issues from all child compilers
      return issues;
    });
  }
}

Hook Best Practices

  1. Always return values in waterfall hooks - Failing to return will break the chain
  2. Handle async operations properly - Use tapPromise for async work in start hook
  3. Don't mutate original objects - Create new objects when modifying in waterfall hooks
  4. Add meaningful plugin names - Use descriptive names for easier debugging
  5. Handle errors gracefully - Don't let hook errors crash the build process
  6. Consider performance - Hooks run on every type check, keep them fast