Runs TypeScript type checker and linter on separate process for webpack builds.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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.
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>;
}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;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];
});
}
}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');
});
}
}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');
});
}
}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.
}
}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;
});
}
}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);
});
}
}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;
});
}
}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
}
}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;
});
}
}