npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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-plugin

Usage

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, and shutdown hooks
  • 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

  1. Initialization: Plugin is instantiated with configuration options
  2. Watch Start: watchRun hook initializes the file watcher when webpack starts watching
  3. File Events: Chokidar detects file changes and triggers callbacks
  4. Compilation Invalidation: Changed files automatically trigger webpack recompilation
  5. Cleanup: watchClose and shutdown hooks 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