or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

file-watching.mdindex.mdinstance-management.mdnotifications-ui.mdplugins.mdserver-proxy.mdsynchronization.md
tile.json

file-watching.mddocs/

File Watching and Reloading

Browser-sync's file watching system monitors your files for changes and triggers appropriate actions - either CSS injection for seamless updates or full browser reloads. It supports glob patterns, ignore rules, and integrates with build tools through streams.

Capabilities

File Configuration

Configure which files to watch and how to respond to changes.

/**
 * Files to watch - can be strings, arrays, or objects with advanced options
 */
files?: string | string[] | FilesConfig[] | boolean;

interface FilesConfig {
    /** Glob patterns to match files */
    match: string | string[];
    /** Custom function to call on file changes */  
    fn?: (event: string, file: string) => void;
    /** Additional options for this file group */
    options?: any;
}

/**
 * File events to respond to (default: ["change"])
 */
watchEvents?: ("add" | "change" | "unlink" | "addDir" | "unlinkDir")[];

/**
 * Auto-watch files in common directories (default: false)
 */
watch?: boolean;

/**
 * Patterns to ignore when watching (default: [])
 */
ignore?: string | string[];

/**
 * Options passed to Chokidar file watcher
 */
watchOptions?: {
    ignoreInitial?: boolean;
    ignored?: string | RegExp | string[];
    persistent?: boolean;
    followSymlinks?: boolean;
    cwd?: string;
    usePolling?: boolean;
    interval?: number;
    binaryInterval?: number;
    alwaysStat?: boolean;
    depth?: number;
    awaitWriteFinish?: boolean | {
        stabilityThreshold?: number;
        pollInterval?: number;
    };
};

Usage Examples:

const browserSync = require('browser-sync');

// Simple file watching
browserSync({
    server: './app',
    files: ['./app/**/*.css', './app/**/*.html']
});

// Auto-watch with ignore patterns
browserSync({
    server: './app',
    watch: true,
    ignore: ['node_modules', '*.log', 'temp/**']
});

// Advanced file configuration
browserSync({
    server: './app',
    files: [
        // CSS files - inject without reload
        {
            match: ['./app/css/**/*.css'],
            fn: function(event, file) {
                console.log(`CSS file ${event}: ${file}`);
                // Custom processing here
            }
        },
        // HTML files - full reload  
        './app/**/*.html',
        // JS files with custom options
        {
            match: ['./app/js/**/*.js'],
            options: {
                ignored: '*.min.js'
            }
        }
    ],
    watchEvents: ['change', 'add', 'unlink']
});

Manual Reload

Trigger browser reloads programmatically for integration with build processes and custom workflows.

/**
 * Reload browsers with optional file specification
 * @param files - Files to reload (optional)
 */
reload(files?: string | string[] | ReloadOptions): void;

interface ReloadOptions {
    /** Use streaming mode */
    stream?: boolean;
    /** Only reload once regardless of number of files */
    once?: boolean;
    /** File patterns to match for reloading */
    match?: string | string[];
}

Usage Examples:

const bs = require('browser-sync').create();

bs.init({
    server: './dist',
    files: false // Disable automatic file watching
});

// Manual reload all browsers
bs.reload();

// Reload specific files
bs.reload('./css/main.css');
bs.reload(['./js/app.js', './templates/*.html']);

// Reload with options
bs.reload({
    stream: false, // Force full reload instead of injection
    match: '**/*.php' // Only reload for PHP files
});

// Integration with build tools
const gulp = require('gulp');

gulp.task('styles', function() {
    return gulp.src('./src/css/**/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./dist/css'))
        .pipe(bs.reload({ stream: true })); // Stream mode for CSS
});

gulp.task('scripts', function() {
    return gulp.src('./src/js/**/*.js')
        .pipe(uglify())
        .pipe(gulp.dest('./dist/js'))
        .on('end', bs.reload); // Full reload for JS
});

Stream Integration

Transform stream for seamless integration with build tools like Gulp, enabling CSS injection and conditional reloading.

/**
 * Transform stream for build tool integration
 * @param options - Stream configuration options
 * @returns Transform stream
 */
stream(options?: StreamOptions): NodeJS.ReadWriteStream;

interface StreamOptions {
    /** Only reload on first file change */
    once?: boolean;
    /** File patterns to match for streaming */
    match?: string | string[];
}

Usage Examples:

const gulp = require('gulp');
const sass = require('gulp-sass');
const browserSync = require('browser-sync').create();

browserSync.init({
    server: './app'
});

// CSS injection without page reload
gulp.task('sass', function() {
    return gulp.src('./scss/**/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./app/css'))
        .pipe(browserSync.stream()); // Inject CSS changes
});

// Conditional streaming based on file types
gulp.task('assets', function() {
    return gulp.src('./src/assets/**/*')
        .pipe(gulp.dest('./dist/assets'))
        .pipe(browserSync.stream({
            match: '**/*.css' // Only stream CSS files
        }));
});

// Stream with once option
gulp.task('templates', function() {
    return gulp.src('./templates/**/*.html')
        .pipe(templateEngine())
        .pipe(gulp.dest('./dist'))
        .pipe(browserSync.stream({
            once: true // Only reload once per task run
        }));
});

Standalone File Watcher

Use browser-sync's file watcher independently of the server for custom file monitoring needs.

/**
 * Watch files for changes using Chokidar
 * @param patterns - Glob patterns to watch
 * @param options - Chokidar options
 * @param callback - Function called on file events
 */
watch(patterns: string, options?: WatchOptions, callback?: (event: string, path: string) => void): void;

Usage Examples:

const browserSync = require('browser-sync');

// Simple file watching
browserSync.watch('./src/**/*.js', function(event, file) {
    console.log(`File ${file} was ${event}`);
    // Custom processing
    if (event === 'change') {
        runTests();
    }
});

// Advanced watching with options
browserSync.watch('./templates/**/*.html', {
    ignoreInitial: true,
    ignored: ['*.tmp', '**/node_modules/**']
}, function(event, file) {
    if (event === 'change') {
        console.log(`Template changed: ${file}`);
        compileTemplates().then(() => {
            browserSync.reload();
        });
    }
});

Reload Control

Fine-tune reload behavior with debouncing, throttling, and injection preferences.

/**
 * Delay before reload after file change (ms) (default: 0)
 */
reloadDelay?: number;

/**
 * Debounce reload events (ms) (default: 500)
 */
reloadDebounce?: number;

/**
 * Throttle reload events (ms) (default: 0)
 */
reloadThrottle?: number;

/**
 * Try to inject CSS changes instead of reload (default: true)
 */
injectChanges?: boolean;

Usage Examples:

const browserSync = require('browser-sync');

// Configure reload timing
browserSync({
    server: './app',
    files: ['./app/**/*.css', './app/**/*.html'],
    reloadDelay: 100, // Wait 100ms before reloading
    reloadDebounce: 1000, // Debounce rapid file changes
    reloadThrottle: 500, // Throttle reload frequency
    injectChanges: true // Prefer CSS injection over reload
});

// Disable CSS injection for debugging
browserSync({
    server: './app', 
    files: ['./app/**/*.css'],
    injectChanges: false // Always full reload
});

Pause and Resume

Control file watching during build processes or maintenance tasks.

/**
 * Pause file change events
 */
pause(): void;

/**
 * Resume paused file watchers
 */
resume(): void;

Usage Examples:

const bs = require('browser-sync').create();

bs.init({
    server: './app',
    files: ['./app/**/*']
});

// Pause during intensive operations
bs.pause();

runLongBuildProcess()
    .then(() => {
        bs.resume();
        bs.reload(); // Reload after build completes
    })
    .catch(err => {
        console.error('Build failed:', err);
        bs.resume();
    });

// Pause/resume with user interaction
process.stdin.on('data', (data) => {
    const input = data.toString().trim();
    if (input === 'pause') {
        bs.pause();
        console.log('File watching paused');
    } else if (input === 'resume') {
        bs.resume();
        console.log('File watching resumed');
    }
});

File Extensions and Fallbacks

Configure how browser-sync handles different file extensions and fallback behavior.

/**
 * File extension fallbacks for certain files
 */
extensions?: string[];

/**
 * Rewrite rules for modifying HTML content during serving
 */
rewriteRules?: Array<{
    match: RegExp;
    fn?: (req: any, res: any, match: string) => string;
    replace?: string;
}>;

Usage Examples:

const browserSync = require('browser-sync');

// File extension fallbacks
browserSync({
    server: './app',
    extensions: ['html'], // Serve index.html for /page requests
    files: ['./app/**/*.html']
});

// HTML rewriting for asset injection
browserSync({
    server: './app',
    rewriteRules: [
        {
            match: /<\/head>/i,
            fn: function(req, res, match) {
                return '<link rel="stylesheet" href="/dev.css">' + match;
            }
        },
        {
            match: /VERSION/g,
            replace: '1.2.3'
        }
    ]
});