Gulp

repository·master·Indexed 12 days ago

https://github.com/gulpjs/gulp

A streaming build system and toolkit for automating repetitive development tasks. Version 5.0.1 features a minimal API and plugin-based ecosystem using Node.js streams. Core functionality includes workflow functions like src(), dest(), and watch(), task orchestration via series() and parallel(), and incremental builds using lastRun().

Tokens
46K
Snippets
122
Records
171
Agent score
97%

What's inside Gulp

  1. Explore the Gulp API documentation

    master

    The Gulp API documentation provides detailed information on core functions and concepts used to build automation workflows. Key areas include:

    • Core Workflow Functions: src() for reading files, dest() for writing files, and watch() for monitoring file changes.
    • Task Orchestration: series() and parallel() for controlling execution order, and task() for defining named tasks.
    • File Abstractions: Understanding Vinyl objects, which represent the files being processed.
    • Advanced Utilities: lastRun() for incremental builds, symlink() for creating symbolic links, and registry() for managing plugin registries.
  2. Explore Gulp recipes for common workflows

    master
    The Gulp recipes collection provides practical solutions and implementation patterns for common automation tasks. These include managing file deletions, setting up live-reloading servers, handling incremental builds, integrating with other tools like Mocha, Browserify, or Rollup, and managing complex stream behaviors.
  3. What is Vinyl and how to use it

    master

    Vinyl is a virtual file format used by Gulp. When you use src(), Gulp generates Vinyl objects to represent files, including their path, contents, and metadata. These objects can be transformed by plugins or persisted to the file system using dest().

    If you need to create your own Vinyl objects manually (instead of using src()), you should use the external vinyl module.

    const Vinyl = require('vinyl');
    
    const file = new Vinyl({
      cwd: '/',
      base: '/test/',
      path: '/test/file.js',
      contents: Buffer.from('var x = 123')
    });
  4. Configure timestamp precision for lastRun()

    master

    Because different file systems and Node versions have varying levels of precision for file modification times (mtime), you can use the precision parameter in lastRun(task, precision) to round the timestamp. This prevents issues where a file's timestamp might not perfectly match the task's completion timestamp due to rounding in the underlying OS or file system.

    Examples:

    • lastRun(someTask) returns 1426000001111
    • lastRun(someTask, 100) returns 1426000001100
    • lastRun(someTask, 1000) returns 1426000001000
    lastRun(someTask, 1000);
  5. How to use Gulp plugins in a pipeline

    master

    Gulp plugins are Node Transform Streams that encapsulate common behavior to transform files. They are typically used within a pipeline between src() and dest() using the .pipe() method. Plugins can modify a file's filename, metadata, or contents.

    To find plugins, search npm using the gulpplugin and gulpfriendly keywords. It is recommended to use small, single-purpose plugins and chain them together like building blocks.

    const { src, dest } = require('gulp');
    const uglify = require('gulp-uglify');
    const rename = require('gulp-rename');
    
    exports.default = function() {
      return src('src/*.js')
        // The gulp-uglify plugin won't update the filename
        .pipe(uglify())
        // So use gulp-rename to change the extension
        .pipe(rename({ extname: '.min.js' }))
        .pipe(dest('output/'));
    }
  6. Access the original working directory via `process.env.INIT_CWD`

    master
    When running the Gulp CLI, Gulp injects an environment variable process.env.INIT_CWD which contains the original directory from which the command was launched. This is useful for resolving paths relative to the user's starting location rather than the gulpfile location.
  7. Modify Vinyl file contents in a plugin

    master

    Within your transform function, you manipulate the file object (an instance of Vinyl).

    Passing files through the stream

    To pass a file to the next plugin in the pipeline, you have two choices:

    1. Call callback(null, file).
    2. Call this.push(file) and then call callback() without a second argument.

    If your plugin generates multiple files from a single input (e.g., unzipping), call this.push(newFile) multiple times before calling the callback().

    Handling different file content types

    Vinyl files can contain contents in three forms. You should check the file type to avoid errors:

    • file.isNull(): The file has no contents (e.g., for rimraf or clean tasks). Simply return callback(null, file).
    • file.isStream(): The contents are a Node.js stream.
    • file.isBuffer(): The contents are a Node.js Buffer.

    Error Handling

    If an error occurs, pass the error as the first argument to the callback(error) function. For plugin-specific errors, it is recommended to use plugin-error.

    var PluginError = require('plugin-error');
    var PLUGIN_NAME = 'gulp-example';
    
    module.exports = function() {
        return through.obj(function(file, encoding, callback) {
            if (file.isNull()) {
                return callback(null, file);
            }
    
            if (file.isStream()) {
                this.emit('error', new PluginError(PLUGIN_NAME, 'Streams not supported!'));
                return callback();
            } else if (file.isBuffer()) {
                this.emit('error', new PluginError(PLUGIN_NAME, 'Buffers not supported!'));
                return callback();
            }
        });
    };
  8. Signal task completion in Gulp

    master

    Gulp requires all tasks to signal when they have finished to avoid the "Did you forget to signal async completion?" warning. Synchronous tasks are not supported. You must signal completion using one of the following methods:

    1. Return a value: Return a Stream, Promise, EventEmitter, ChildProcess, or Observable. Gulp will monitor these for success or error.
    2. Use an error-first callback: If you do not return anything, Gulp passes a callback function (conventionally named cb) as the first argument to your task. Call cb() to signal success or cb(err) to signal an error.
    3. Use an async function: Defining a task as an async function automatically wraps it in a promise, allowing you to use await within the task body.
  9. Define asynchronous Gulp tasks

    master

    A Gulp task is an asynchronous JavaScript function. Because Gulp relies on asynchronous completion signals, synchronous tasks are not supported.

    To signal task completion, a task must either:

    1. Accept an error-first callback: (cb) => { ... cb(); }
    2. Return a Stream
    3. Return a Promise
    4. Return an EventEmitter
    5. Return a ChildProcess
    6. Return an Observable
  10. Understand and use globs in gulp.src()

    master

    A glob is a string of literal and/or wildcard characters used to match filepaths. The src() method uses globs to determine which files your pipeline will operate on. You can provide a single glob string or an array of globs.

    Important Requirements:

    • At least one match must be found for your glob(s), otherwise src() will error.
    • When using an array of globs, negative globs (prefixed with !) will remove matches from any positive glob.
    • Avoid using Node's path methods (like path.join), __dirname, __filename, or process.cwd() to construct globs, as they may use \ as a separator on Windows, which is reserved as an escape character in globs. Always use / as the separator.
    // Example of passing an array of globs to src()
    gulp.src(['scripts/**/*.js', '!scripts/vendor/**'])
  11. How Gulpfiles work

    master

    A gulpfile is a file named gulpfile.js (or Gulpfile.js) located in your project directory. It is automatically loaded when you execute the gulp command.

    While you will frequently use Gulp APIs such as src(), dest(), series(), and parallel(), the file is essentially a standard Node.js module. You can use any vanilla JavaScript or Node modules within it. To register tasks with Gulp's task system, you must export the functions you want to run as tasks.

  12. Avoid forward references by using named functions

    master

    In modern Gulp, you should avoid using string references to tasks that haven't been registered yet (forward references). Using strings to reference tasks while simultaneously using exports for registration will result in a "Task never defined" error.

    Best Practice: Always use named functions instead of string references when composing tasks to ensure faster task runtime and avoid errors.