@kouovo/ph-webpack-plugin
v0.1.46
Published
A Webpack plugin for watching file changes outside of the standard Webpack watch scope with customizable patterns and event handling.
Readme
@kouovo/ph-webpack-plugin
A Webpack plugin for watching file changes outside of the standard Webpack watch scope with customizable patterns and event handling.
Overview
The @kouovo/ph-webpack-plugin package provides a flexible file watching system for Webpack build processes. It allows you to monitor directories and files that are outside of Webpack's standard watch scope with customizable include/exclude patterns and event callbacks.
Installation
npm install @kouovo/ph-webpack-plugin
# or
pnpm add @kouovo/ph-webpack-plugin
# or
yarn add @kouovo/ph-webpack-pluginUsage
Basic Configuration
import { WebpackWatcherPlugin } from '@kouovo/ph-webpack-plugin';
const config = {
// ... other webpack configuration
plugins: [
new WebpackWatcherPlugin({
watchDir: './src/assets',
include: ['**/*.json', '**/*.md'],
exclude: ['node_modules/**', 'dist/**'],
onChange: (file, event) => {
console.log(`File ${file} was ${event}`);
},
}),
],
};
export default config;Multiple Directories
new WebpackWatcherPlugin({
watchDir: ['./config', './data', './templates'],
include: '**/*',
exclude: ['**/*.log', '**/temp/**'],
onChange: (file, event) => {
if (event === 'change') {
console.log(`Configuration updated: ${file}`);
}
}
})Advanced Usage with File Processor
import { WebpackWatcherPlugin, createFileProcessor } from '@kouovo/ph-webpack-plugin';
const processor = createFileProcessor({
onAdd: (file) => {
console.log(`New file added: ${file}`);
// Handle new file logic
},
onChange: (file) => {
console.log(`File changed: ${file}`);
// Handle file modification logic
},
onRemove: (file) => {
console.log(`File removed: ${file}`);
// Handle file removal logic
},
process: (file, event) => {
// Custom processing logic for all events
if (file.endsWith('.json')) {
validateJsonFile(file);
}
}
});
const config = {
// ... other webpack configuration
plugins: [
new WebpackWatcherPlugin({
watchDir: ['./src/locales', './src/assets'],
include: ['**/*.json', '**/*.png', '**/*.svg'],
exclude: ['node_modules/**', 'dist/**', '**/*.test.*'],
onChange: processor,
enableLog: true,
watchOptions: {
awaitWriteFinish: {
stabilityThreshold: 200,
pollInterval: 20,
},
},
}),
],
};
export default config;API Reference
WebpackWatcherPlugin
A Webpack plugin class that watches external directories for file changes.
Constructor Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| watchDir | string \| string[] | Required | Directory or directories to watch |
| include | string \| string[] | '**/*' | Glob patterns for files to include |
| exclude | string \| string[] | 'node_modules/**' | Glob patterns for files to exclude |
| onChange | (file: string, event: FileEvent) => void | () => {} | Callback function for file changes |
| watchOptions | chokidar.WatchOptions | {} | Additional options for the underlying chokidar watcher |
| enableLog | boolean | true | Enable console logging for file events |
File Events
'add'- A new file has been added'change'- An existing file has been modified'unlink'- A file has been removed
Example with Advanced Options
new WebpackWatcherPlugin({
watchDir: './config',
include: '**/*.env',
enableLog: false,
watchOptions: {
usePolling: true,
interval: 1000,
ignoreInitial: false,
awaitWriteFinish: {
stabilityThreshold: 300,
pollInterval: 50
}
},
onChange: (file, event) => {
if (file.includes('.env')) {
console.log(`Environment file ${event}: ${file}`);
// Trigger webpack recompilation
}
}
})createFileProcessor(options)
Creates a file processor function with specific event handlers.
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| process | (file: string, event: FileEvent) => void | () => {} | General processor for all events |
| onAdd | (file: string) => void | null | Handler for file addition events |
| onChange | (file: string) => void | null | Handler for file modification events |
| onRemove | (file: string) => void | null | Handler for file removal events |
Example
const processor = createFileProcessor({
onAdd: (file) => {
console.log(`📄 New file: ${path.basename(file)}`);
// Index new file
indexFile(file);
},
onChange: (file) => {
console.log(`✏️ Modified: ${path.basename(file)}`);
// Reprocess file
processFile(file);
},
onRemove: (file) => {
console.log(`🗑️ Removed: ${path.basename(file)}`);
// Clean up references
removeFromIndex(file);
},
process: (file, event) => {
// Log all events with timestamp
console.log(`[${new Date().toISOString()}] ${event.toUpperCase()}: ${file}`);
}
});Features
Webpack Integration
- Hook Integration: Integrates with Webpack's
watchRun,watchClose, andshutdownhooks - Compilation Invalidation: Automatically triggers Webpack recompilation on file changes
- Context Awareness: Respects Webpack's context configuration for path resolution
Pattern Matching
- Glob Patterns: Uses micromatch for flexible file pattern matching
- Include/Exclude: Fine-grained control over which files to watch
- Multiple Patterns: Support for arrays of patterns for complex matching
File Watching
- Chokidar Integration: Built on robust file watching library
- Debouncing: Built-in write stabilization to prevent duplicate events
- Cross-Platform: Works consistently across Windows, macOS, and Linux
Performance
- Efficient Watching: Optimized for performance with configurable options
- Memory Management: Automatic cleanup when webpack compilation ends
- Selective Processing: Only processes files matching include patterns
Use Cases
Configuration Management
new WebpackWatcherPlugin({
watchDir: './config',
include: ['*.json', '*.yaml', '*.env'],
onChange: (file, event) => {
if (event === 'change') {
// Reload configuration and trigger rebuild
reloadConfig(file);
// The plugin automatically invalidates webpack compilation
}
}
})Asset Processing
new WebpackWatcherPlugin({
watchDir: './src/assets/raw',
include: ['**/*.png', '**/*.jpg', '**/*.svg'],
onChange: async (file, event) => {
if (event === 'add' || event === 'change') {
// Process and optimize images
await optimizeImage(file);
// Generate different sizes
await generateImageSizes(file);
// Webpack will automatically rebuild after this
}
}
})Template Compilation
new WebpackWatcherPlugin({
watchDir: './templates',
include: ['**/*.hbs', '**/*.mustache'],
onChange: async (file, event) => {
if (event !== 'unlink') {
// Compile templates
await compileTemplate(file);
// Update template cache
updateTemplateCache(file);
}
}
})Locale File Management
new WebpackWatcherPlugin({
watchDir: './locales',
include: '**/*.json',
onChange: (file, event) => {
// Regenerate locale bundles
generateLocaleBundles();
// The webpack compilation will be invalidated automatically
}
})Webpack Integration Details
Plugin Lifecycle
- Initialization: Plugin is instantiated with configuration options
- Watch Start:
watchRunhook initializes the file watcher when webpack starts watching - File Events: Chokidar detects file changes and triggers callbacks
- Compilation Invalidation: Changed files automatically trigger webpack recompilation
- Cleanup:
watchCloseandshutdownhooks ensure proper watcher cleanup
Compilation Integration
// The plugin automatically integrates with webpack's compilation process
new WebpackWatcherPlugin({
watchDir: './external-data',
onChange: (file, event) => {
// Your custom logic here
processFile(file, event);
// No need to manually trigger recompilation -
// the plugin handles this automatically
}
})Comparison with Vite Plugin
| Feature | Webpack Plugin | Vite Plugin |
|---------|----------------|-------------|
| Architecture | Webpack compilation hooks | Vite dev server integration |
| Hot Reload | Webpack invalidation | WebSocket integration |
| Initialization | watchRun hook | configureServer hook |
| Cleanup | watchClose + shutdown hooks | HTTP server close |
| Build Integration | Both build + watch modes | Development server only |
| Recompilation | Automatic via invalidation | Manual via WebSocket events |
Error Handling
The plugin includes comprehensive error handling:
new WebpackWatcherPlugin({
watchDir: './config',
onChange: (file, event) => {
try {
processFile(file, event);
} catch (error) {
console.error(`Error processing ${file}:`, error);
// Handle error appropriately
}
},
watchOptions: {
// Chokidar will emit 'error' events which are logged by the plugin
}
})Automatic Error Recovery
- Watcher Errors: Automatically logged and handled gracefully
- File Processing Errors: User callback errors don't crash the watcher
- Cleanup Errors: Proper cleanup even if errors occur during shutdown
Performance Optimization
Watch Options
new WebpackWatcherPlugin({
watchDir: './large-directory',
watchOptions: {
// Use polling for network drives
usePolling: false,
// Increase stability threshold for large files
awaitWriteFinish: {
stabilityThreshold: 300,
pollInterval: 50
},
// Ignore initial scan for performance
ignoreInitial: true
}
})Selective Watching
new WebpackWatcherPlugin({
watchDir: './src',
// Only watch specific file types
include: ['**/*.json', '**/*.yaml'],
// Exclude heavy directories
exclude: [
'**/node_modules/**',
'**/dist/**',
'**/.git/**',
'**/coverage/**'
]
})Logging Control
new WebpackWatcherPlugin({
watchDir: './config',
enableLog: process.env.NODE_ENV === 'development', // Only log in development
onChange: (file, event) => {
// Your logic here
}
})TypeScript Support
The package includes full TypeScript support with exported types:
import type {
WebpackWatcherPluginOptions,
FileEvent,
FileProcessorOptions
} from '@kouovo/ph-webpack-plugin';
const options: WebpackWatcherPluginOptions = {
watchDir: './data',
include: '**/*.ts',
onChange: (file: string, event: FileEvent) => {
// Type-safe event handling
}
};Dependencies
- chokidar: File watching with cross-platform support
- micromatch: Fast glob pattern matching
- webpack: Peer dependency for plugin integration
License
MIT
