Gulp4.0 Getting Started Guide

Keywords: node.js Javascript npm less sass

install

Gulp website

gulp4.0 separates the cli from the core, so you need to install both packages separately, with the following environmental requirements:

node >= 8.11.1
npm >= 5.6.0
npx >= 9.7.1
  • Global Installation gulp-cli
npm i -g gulp-cli
  • Locally installed gulp
npm i -D gulp
  • View version number
$ gulp -v

# output

CLI version: 2.2.0
Local version: 4.0.2

configuration file

Create a gulpfile.js file in the project root directory (if ts or Babel is used, gulpfile.ts, gulpfile.babel.js can also be used instead), which is the configuration file that gulp reads by default, where we can configure the task s we need.
If you have more or more complex tasks, you can create a gulpfile.js directory and split task into multiple files in the directory as long as you have an index.js as the entry.

Task

task is divided into two types:

  • Private tasks: A function in the configuration file that can only be used in this file
  • Public tasks: Export Private tasks for gulp command execution
const { series, parallel } = require('gulp');
// Private tasks
function clean(cb) {
  // body omitted
  cb();
}
// Private tasks
function build(cb) {
  // body omitted
  cb();
}

exports.build = build; // Public tasks, execute gulp build
exports.default = series(clean, parallel(css, javascript)); // Public tasks, execute gulp

Be careful:
In task, when the operation is complete, we must tell gulp that the task has been completed by cb() or return.

// cb
function clean(cb) {
  del(['dist]);
    cb();
});
// return 
function minifyjs() {
  return src('src/**/*.js')
    .pipe(minify())
    .pipe(dest('dist'));
});
function promiseTask() {
  return new Promise(function(resolve, reject) {
    // body omitted
    resolve();
  });
});

Run task

gulp <export task name> 
gulp // task exported to default allows gulp directly

Combined task

  • series: sequence (sequential execution)
// Tak1 executes before task2 executes
exports.taskName = series(task1, task2)
  • Parallel: parallel (simultaneous execution)
// Tak1 and task2 execute simultaneously
exports.taskName = parallel(task1, task2)
  • Mixed use:
exports.taskName = series(clean, parallel(css, javascript))

Input and Output

gulp uses Unix's pipe idea for reference. Files are processed by streaming. The output of the previous step is used as the input of the next step. Files are not written to disk in the middle. Files are only output when dest, so it is very fast and efficient.

gulp provides src and dest methods for file read-in and output operations respectively, and pipe pipeline methods for chain execution of other operations.

const { src, dest } = require('gulp');

// Output all js from the src directory to the output directory
exports.default = function() {
  return src('src/*.js')
    .pipe(dest('output/'));
}

If we want to add files in the middle, we can do the following:

const { src, dest } = require('gulp');
const uglify = require('gulp-uglify');

exports.default = function() {
  return src('src/*.js')
    .pipe(uglify())
    .pipe(src('vendor/*.js')) // Add Files
    .pipe(dest('output/'));
}

Of course, we can also do multiple outputs:

const { src, dest } = require('gulp');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');

exports.default = function() {
  return src('src/*.js')
    .pipe(babel())
    .pipe(dest('temp/'))
    .pipe(uglify())
    .pipe(dest('output/'));
}

File Matching

Often, when using the src method, we need to input more than one file or a class of files, not just a specific file, so we can use the matching rules provided by gulp to process them.

  • "src/file.js": single file
  • ["src/file1,src/file2.js"]: Multiple files
  • *: All files
src('src/*.js') // All js files in src's own directory, not in descendant folders
src('src/a*c.js') 
  • **:0 or more folders
src('src/**/*.js') // src directory All js files, including descendant folders
  • {}: Multiple attributes
src('src/*.{jpg,png,gif}') // All jpg, png, and gif files in the src's own directory
  • !: Exclude
src(['**/*.js', '!node_modules/**']) // All js files except under node_modules

Note: File matching strings received by SRC are interpreted sequentially, so you can write gulp.src (['.js','!b.js','bad.js']) (excluding all JS files that start with b but excluding bad.js)

Use plug-ins and other libraries

gulp recommends that each plug-in focus only on a small part of the work, then connect them through pipe to accomplish what we need to do.

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/'));
}

Of course, in addition to plug-ins, we can also use other libraries:

const del = require('delete');

exports.default = function(cb) {
  // Use the `delete` module directly, instead of using gulp-rimraf
  del(['output/*.js'], cb);
}

Finally, you can use the through2 plug-in to process it yourself inline:

const { src, dest } = require('gulp');
const uglify = require('uglify-js');
const through2 = require('through2');

exports.default = function() {
  return src('src/*.js')
    // Instead of using gulp-uglify, you can create an inline plugin
    .pipe(through2.obj(function(file, _, cb) {
      if (file.isBuffer()) {
        const code = uglify.minify(file.contents.toString())
        file.contents = Buffer.from(code)
      }
      cb(null, file);
    }))
    .pipe(dest('output/'));
}

Listen Files

We can use the watch method to listen for changes to the file to perform the appropriate processing tasks when the changes are made.

const { watch, series } = require('gulp');

function clean(cb) {
  // body omitted
  cb();
}

function javascript(cb) {
  // body omitted
  cb();
}

function css(cb) {
  // body omitted
  cb();
}

exports.default = function() {
  watch('src/*.css', css);
  watch('src/*.js', series(clean, javascript));
};

API

src(globs, [options]): input

  • globs[string|array]: Path matching rules for files to be processed
  • options: Configuration items, Click here for details
const { src, dest } = require('gulp');

function copy() {
  return src('input/*.js', { sourcemaps: true })
    .pipe(dest('output/'));
}

dest(directory, [options]): output

const { src, dest } = require('gulp');
const uglify = require('gulp-uglify');

src('input/**/*.js', { sourcemaps: true })
  .pipe(uglify())
  .pipe(dest('output/', { sourcemaps: '.' }));

series(...tasks): Perform multiple tasks sequentially

  • tasks[function|string]: task name or function
const { series } = require('gulp');

function javascript(cb) {
  // body omitted
  cb();
}

function css(cb) {
  // body omitted
  cb();
}

exports.build = series(javascript, css);

parallel(...tasks): multiple tasks executed simultaneously

  • tasks[function|string]: task name or function
const { parallel } = require('gulp');

function javascript(cb) {
  // body omitted
  cb();
}

function css(cb) {
  // body omitted
  cb();
}

exports.build = parallel(javascript, css);

watch(globs, [options], [task]): file listening

  • globs[string|array]: file to listen on
  • options: Configuration items, Click here for details
  • task[function|string]: Task or operation to be performed
const { watch } = require('gulp');

watch(['input/*.js', '!input/something.js'], function(cb) {
  // body omitted
  cb();
});

The listening method returns a total of instances that provide the following methods:

watcher.on(eventName, eventHandler)

  • eventName[string]: The name of the event, which can be add, addDir, change, unlink, unlinkDir, ready, error, or all
  • eventHandler[function]: Event handler function that receives path and stats parameters.
const { watch } = require('gulp');

const watcher = watch(['input/*.js']);

watcher.on('change', function(path, stats) {
  console.log(`File ${path} was changed`);
});

watcher.on('add', function(path, stats) {
  console.log(`File ${path} was added`);
});

watcher.on('unlink', function(path, stats) {
  console.log(`File ${path} was removed`);
});

watcher.close();

watcher.close(): Close the file listener

watcher.add(globs): Add files to the listener

  • globs[string|array]: file to add

watcher.unwatch(globs): Remove files from listeners

  • globs[string|array]: file to remove

task([taskName], taskFunction): Define a task (4.0 recommends using function instead of this method)

  • taskName[string]: Task name
  • taskFunction[function]: Processing function
const { task } = require('gulp');

task('build', function(cb) {
  // body omitted
  cb();
});

const build = task('build');

lastRun(task, [precision]): Gets the timestamp of the last run completed by the task

  • task[function|string]: Specify the acquired task
  • precision[number]: precision, default 1000

This method can be used for incremental compilation.

const { src, dest, lastRun, watch } = require('gulp');
const imagemin = require('gulp-imagemin');

function images() {
  return src('src/images/**/*.jpg', { since: lastRun(images) })
    .pipe(imagemin())
    .pipe(dest('build/img/'));
}

exports.default = function() {
  watch('src/images/**/*.jpg', images);
};

tree([options]): Get task dependencies

  • options[object]:deep defaults to false, returning only the top-level task, and if true, the entire task tree.
gulp.tree({ deep: true })

These are the APIs I use most, and other APIs can view the official documentation themselves.

Common Plugins

  • gulp-clean: for cleaning;
  • gulp-notify: used to print message text;
  • gulp-rename: used to modify the name;
  • gulp-concat: used to merge files;
  • gulp-zip: used to generate a zip compressed package;
  • gulp-minify-css: for compressing css;
  • gulp-autoprefixer: used to prefix css;
  • gulp-imagemin: used to optimize pictures;
  • gulp-uglify: for compressing js;
  • amd-optimize: for amd module reference compilation;
  • gulp-import-css: If the CSS file is imported through import, you can use this plug-in for merge optimization;
  • gulp-rev-replace: for replacement;
  • gulp-useref: introducing build tag for replacement;
  • gulp-rev: Generate md5 file name;
  • gulp-filter: Files are filtered;
  • gulp-header: Write comments to the header of the file after compression
  • gulp-if: make logical judgments
  • gulp-size: get file size
  • gulp-less: Compile less files
  • gulp-sass: compile sass files
  • gulp-file-include: introducing files
  • gulp-sourcemaps: Generate map files
  • Gulp-live reload: automatic refresh
  • gulp-clean-css:css compression
  • browserSync: Start server and start hot updates
  • gulp-plumber: Monitor the workflow for errors and prevent exiting gulp directly when errors are encountered
  • gulp-rev: Add version number to file name
  • gulp-css-spritesmith: Automatically generate sprite maps from CSS files

If you are looking for a gulp plug-in, there are two general places:

Summary:

gulp itself is very simple, with very few APIs available, but it is simple enough.Once you understand these api s, you may find it most complex or understand the use of each plug-in.

In fact, the construction tools (gulp, webpack, and so on) are relatively simple in themselves, which is what they should look like, and they are complex in themselves, so I am not lazy to use them.But in the process of use, I think there are two difficulties:

  • How to establish a set of reasonable, configurable construction process that can really improve our work efficiency
  • How to quickly find the most appropriate plug-in and use it when you need a feature

Finally, I am ignorant of school, there are inappropriate, welcome to correct.

Posted by Navajo on Sun, 16 Jun 2019 09:14:44 -0700