npm package: @kouovo/ph-vite-plugin
Description: A Vite plugin for watching file changes outside of the standard Vite watch scope with customizable patterns and event handling.
Latest version: 0.1.46

# @kouovo/ph-vite-plugin

A Vite plugin for watching file changes outside of the standard Vite watch scope with customizable patterns and event handling.

## Overview

The `@kouovo/ph-vite-plugin` package provides a flexible file watching system for Vite development servers. It allows you to monitor directories and files that are outside of Vite's standard watch scope with customizable include/exclude patterns and event callbacks.

## Installation

```bash
npm install @kouovo/ph-vite-plugin
# or
pnpm add @kouovo/ph-vite-plugin
# or
yarn add @kouovo/ph-vite-plugin
```

## Usage

### Basic Configuration

```javascript
// vite.config.js
import { defineConfig } from 'vite';
import { viteWatcherPlugin } from '@kouovo/ph-vite-plugin';

export default defineConfig({
  plugins: [
    viteWatcherPlugin({
      watchDir: './external-data',
      include: ['**/*.json', '**/*.yml'],
      exclude: ['**/node_modules/**', '**/.git/**'],
      onChange: (file, event) => {
        console.log(`File ${event}: ${file}`);
      }
    })
  ]
});
```

### Multiple Directories

```javascript
viteWatcherPlugin({
  watchDir: ['./config', './data', './templates'],
  include: '**/*',
  exclude: ['**/*.log', '**/temp/**'],
  onChange: (file, event) => {
    if (event === 'change') {
      console.log(`Configuration updated: ${file}`);
    }
  }
})
```

### Advanced Configuration with File Processor

```javascript
import { viteWatcherPlugin, createFileProcessor } from '@kouovo/ph-vite-plugin';

const fileProcessor = createFileProcessor({
  onAdd: (file) => console.log(`New file added: ${file}`),
  onChange: (file) => console.log(`File modified: ${file}`),
  onRemove: (file) => console.log(`File deleted: ${file}`),
  process: (file, event) => {
    // Custom processing logic for all events
    if (file.endsWith('.json')) {
      // Handle JSON file changes
      validateJsonFile(file);
    }
  }
});

export default defineConfig({
  plugins: [
    viteWatcherPlugin({
      watchDir: './src/data',
      include: ['**/*.json', '**/*.yaml'],
      onChange: fileProcessor
    })
  ]
});
```

## API Reference

### `viteWatcherPlugin(options)`

Creates a Vite plugin that watches external directories for file changes.

#### 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` | `ChokidarOptions` | `{}` | Additional options for the underlying chokidar watcher |

#### File Events

- `'add'` - A new file has been added
- `'change'` - An existing file has been modified
- `'unlink'` - A file has been removed

#### Example with Watch Options

```javascript
viteWatcherPlugin({
  watchDir: './config',
  include: '**/*.env',
  watchOptions: {
    usePolling: true,
    interval: 1000,
    ignoreInitial: false,
    awaitWriteFinish: {
      stabilityThreshold: 200,
      pollInterval: 20
    }
  },
  onChange: (file, event) => {
    if (file.includes('.env')) {
      console.log(`Environment file ${event}: ${file}`);
      // Trigger environment reload
    }
  }
})
```

### `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

```javascript
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
    console.log(`[${new Date().toISOString()}] ${event.toUpperCase()}: ${file}`);
  }
});
```

## Features

### 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

### Vite Integration
- **WebSocket Events**: Sends custom events to client via Vite's WebSocket
- **Server Lifecycle**: Automatically manages watcher lifecycle with Vite server
- **Path Normalization**: Consistent path handling across platforms

### Performance
- **Efficient Watching**: Optimized for performance with configurable options
- **Memory Management**: Automatic cleanup when server shuts down
- **Selective Processing**: Only processes files matching include patterns

## Use Cases

### Configuration Management
```javascript
viteWatcherPlugin({
  watchDir: './config',
  include: ['*.json', '*.yaml', '*.env'],
  onChange: (file, event) => {
    if (event === 'change') {
      // Reload configuration
      reloadConfig(file);
      // Notify client of config change
      notifyConfigChange(file);
    }
  }
})
```

### Asset Processing
```javascript
viteWatcherPlugin({
  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);
    }
  }
})
```

### Data Synchronization
```javascript
viteWatcherPlugin({
  watchDir: ['./data', './external-apis'],
  include: '**/*.json',
  exclude: '**/.cache/**',
  onChange: (file, event) => {
    // Sync data changes to development environment
    syncDataToDevEnvironment(file, event);
  }
})
```

### Template Compilation
```javascript
viteWatcherPlugin({
  watchDir: './templates',
  include: ['**/*.hbs', '**/*.mustache'],
  onChange: async (file, event) => {
    if (event !== 'unlink') {
      // Compile templates
      await compileTemplate(file);
      // Update template cache
      updateTemplateCache(file);
    }
  }
})
```

## Client-Side Integration

The plugin sends WebSocket events that can be received on the client side:

```javascript
// In your Vite client code
if (import.meta.hot) {
  import.meta.hot.on('vite-watch-plugin-change', (data) => {
    console.log(`External file ${data.event}: ${data.file}`);
    
    // React to external file changes
    if (data.file.includes('config.json')) {
      // Reload application configuration
      location.reload();
    }
  });
}
```

## TypeScript Support

The package includes full TypeScript support with exported types:

```typescript
import type { 
  ViteWatchPluginOptions, 
  FileEvent, 
  FileProcessorOptions 
} from '@kouovo/ph-vite-plugin';

const config: ViteWatchPluginOptions = {
  watchDir: './data',
  include: '**/*.ts',
  onChange: (file: string, event: FileEvent) => {
    // Type-safe event handling
  }
};
```

## Error Handling

The plugin includes comprehensive error handling:

```javascript
viteWatcherPlugin({
  watchDir: './config',
  onChange: (file, event) => {
    try {
      processFile(file, event);
    } catch (error) {
      console.error(`Error processing ${file}:`, error);
      // Handle error appropriately
    }
  }
})
```

## Performance Optimization

### Watch Options
```javascript
viteWatcherPlugin({
  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
```javascript
viteWatcherPlugin({
  watchDir: './src',
  // Only watch specific file types
  include: ['**/*.json', '**/*.yaml'],
  // Exclude heavy directories
  exclude: [
    '**/node_modules/**',
    '**/dist/**',
    '**/.git/**',
    '**/coverage/**'
  ]
})
```

## Dependencies

- **chokidar**: File watching with cross-platform support
- **micromatch**: Fast glob pattern matching
- **vite**: Peer dependency for plugin integration

## License

MIT