or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-gulp-changed

Gulp plugin that optimizes build processes by only passing through files that have been modified since the last build

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/gulp-changed@5.0.x

To install, run

npx @tessl/cli install tessl/npm-gulp-changed@5.0.0

index.mddocs/

gulp-changed

gulp-changed is a Gulp plugin that optimizes build processes by only passing through files that have been modified since the last build. It offers multiple comparison strategies including modification time checking and content-based comparison, with built-in comparators for common use cases and support for custom comparison functions.

Package Information

  • Package Name: gulp-changed
  • Package Type: npm
  • Language: JavaScript (ES Module)
  • Installation: npm install --save-dev gulp-changed

Core Imports

import gulpChanged, { compareLastModifiedTime, compareContents } from 'gulp-changed';

Basic Usage

import gulp from 'gulp';
import gulpChanged from 'gulp-changed';
import ngAnnotate from 'gulp-ng-annotate'; // Example processor

const SOURCE = 'src/*.js';
const DESTINATION = 'dist';

export default function build() {
  return gulp.src(SOURCE)
    .pipe(gulpChanged(DESTINATION))
    // ngAnnotate will only get the files that
    // changed since the last time it was run
    .pipe(ngAnnotate())
    .pipe(gulp.dest(DESTINATION));
}

Capabilities

Main Plugin Function

Creates a Gulp transform stream that filters out unchanged files based on comparison with destination files.

/**
 * Create a gulp plugin that only passes through changed files
 * @param destination - Destination directory path or function returning destination path
 * @param options - Configuration options for comparison behavior
 * @returns Transform stream for use in gulp pipeline
 */
function gulpChanged(destination: string | ((file: Vinyl) => string), options?: ChangedOptions): Transform;

interface ChangedOptions {
  /** Working directory the folder is relative to (default: process.cwd()) */
  cwd?: string;
  /** Function that determines whether the source file is different from the destination file */
  hasChanged?: (sourceFile: Vinyl, targetPath: string) => Promise<Vinyl | undefined>;
  /** Extension of the destination files (useful if different from source) */
  extension?: string;
  /** Function to transform the path to the destination file */
  transformPath?: (newPath: string) => string;
}

Usage Examples:

// Basic usage with destination directory
gulp.src('src/**/*.js')
  .pipe(gulpChanged('dist'))
  .pipe(babel())
  .pipe(gulp.dest('dist'));

// With different file extension
gulp.src('src/**/*.jade')
  .pipe(gulpChanged('app', {extension: '.html'}))
  .pipe(jade())
  .pipe(gulp.dest('app'));

// With custom path transformation
gulp.src('src/content/*.md')
  .pipe(gulpChanged('dist', {
    transformPath: (newPath) => path.join(
      path.dirname(newPath), 
      path.basename(newPath, '.md'), 
      'index.html'
    )
  }))
  .pipe(marked())
  .pipe(gulp.dest('dist'));

// With function-based destination
gulp.src('src/**/*.js')
  .pipe(gulpChanged((file) => `dist/${file.relative.split('/')[0]}`))
  .pipe(babel())
  .pipe(gulp.dest('dist'));

Last Modified Time Comparator

Built-in comparator that compares files based on modification time. This is the default comparison method.

/**
 * Compare files based on modification time
 * @param sourceFile - Source vinyl file object with stat information
 * @param targetPath - Absolute path to target file for comparison
 * @returns Promise resolving to sourceFile if changed, undefined if not
 */
async function compareLastModifiedTime(sourceFile: Vinyl, targetPath: string): Promise<Vinyl | undefined>;

Usage Example:

// Explicitly use modification time comparison (this is the default)
gulp.src('src/**/*.js')
  .pipe(gulpChanged('dist', {hasChanged: compareLastModifiedTime}))
  .pipe(babel())
  .pipe(gulp.dest('dist'));

Content-Based Comparator

Built-in comparator that compares files based on actual content differences rather than modification time.

/**
 * Compare files based on content differences
 * @param sourceFile - Source vinyl file object with contents buffer
 * @param targetPath - Absolute path to target file for comparison
 * @returns Promise resolving to sourceFile if changed, undefined if not
 */
async function compareContents(sourceFile: Vinyl, targetPath: string): Promise<Vinyl | undefined>;

Usage Example:

// Use content-based comparison for more accurate change detection
gulp.src('src/**/*.js')
  .pipe(gulpChanged('dist', {hasChanged: compareContents}))
  .pipe(babel())
  .pipe(gulp.dest('dist'));

Types

// Vinyl file object (from vinyl package)
interface Vinyl {
  /** Current working directory */
  cwd: string;
  /** Base directory for relative paths */
  base: string;
  /** Full file path */
  path: string;
  /** Relative file path from base */
  relative: string;
  /** File contents as Buffer or Stream */
  contents: Buffer | Stream | null;
  /** File system stat object */
  stat?: {
    /** Modification time in milliseconds */
    mtimeMs: number;
    [key: string]: any;
  };
}

// Transform stream (from Node.js streams)
interface Transform extends Stream.Transform {
  /** Write a file to the stream */
  write(file: Vinyl): boolean;
  /** End the stream */
  end(): void;
  /** Event emitted when stream ends */
  on(event: 'end', callback: () => void): this;
  /** Event emitted for each file passing through */
  on(event: 'data', callback: (file: Vinyl) => void): this;
}

Error Handling

The plugin handles several error conditions:

  • Missing destination: Throws Error('gulp-changed: \dest` required')` if no destination is provided
  • Invalid transformPath: Throws Error('gulp-changed: \options.transformPath` needs to be a function')` if transformPath is not a function
  • Invalid transformPath return: Throws TypeError('\options.transformPath` needs to return a string')` if transformPath doesn't return a string
  • File system errors: Gracefully handles ENOENT errors (file doesn't exist in destination) by passing the file through
  • Other file system errors: Re-throws other file system errors for proper error handling

Advanced Usage Patterns

Custom Comparator Function

You can provide a custom comparator function for specialized comparison logic:

function customComparator(sourceFile, targetPath) {
  // Custom logic here - must return Promise<Vinyl | undefined>
  // Return sourceFile if it should be processed, undefined if not
  return Promise.resolve(sourceFile);
}

gulp.src('src/**/*.js')
  .pipe(gulpChanged('dist', {hasChanged: customComparator}))
  .pipe(babel())
  .pipe(gulp.dest('dist'));

Working Directory Configuration

Configure the working directory for relative path resolution:

gulp.src('src/**/*.js')
  .pipe(gulpChanged('dist', {
    cwd: '/custom/working/directory'
  }))
  .pipe(babel())
  .pipe(gulp.dest('dist'));