A list,

Gulp >> is a stream-based automated build system that builds code during front-end development. Gulp not only optimizes web resources, but also automates many repetitive tasks during development using the right tools. Using gulp, we can not only have fun writing code, but also greatly improve our work efficiency.

Gulp is an automatic task runner based on nodeJS, which can automatically complete javascript/sass/less/HTML/image/CSS files test, check, merge, compress, format, browser automatic refresh, deployment file generation, etc. And listen for the file to repeat the specified steps after changes. In implementation, Gulp borrows the PIPE idea from the Unix operating system, where the output of the former level becomes the input of the latter level, making it very simple to operate. In this chapter, you’ll learn how to use GULp to change the development process to make development faster and more efficient.

Gulp features:

  • Task-based: All build operations are called tasks in GULP
  • Stream-based: All file operations in gulp are stream-based. (Gulp has its own memory. Gulp uses an API to stream source files into the memory.

Gulp vs Grunt

Gulp aims to replace Grunt

According to gulp’s documentation, the main features it strives to implement are:

  • Easy to use: Using code over configuration, gulp makes simple things simple and complex tasks manageable.
  • Efficient: Build faster by taking advantage of Node.js’ powerful streams and eliminating the need to write intermediate files to disk.
  • High quality: Gulp’s strict plug-in guidelines ensure that plug-ins are simple and work the way you expect them to.
  • Easy to learn: By keeping the API to a minimum, you can learn Gulp in a very short time. The build is just what you would expect: a series of flow pipes.

Gulp simplifies task writing with a policy of flow and code over configuration.

Third, gulp API

With gulp, there are only four apis to know: gulp.task(), gulp.src(), gulp.dest(), and gulp.watch(), so it’s easy to learn.

Before we begin, we recommend that you take a look at some concepts in Gulp.

1. gulp.src()

Read the data source and create a stream to read Vinyl objects from the file system. Note that the contents of this stream are not the original file stream. Instead, they are a Vinyl files that store the path, file name, and content of the original file. You just need to understand that you can use this method to read the files you need to manipulate. The syntax is:

gulp.src(globs, [options])
Copy the code

Parameter interpretation

  • Globs: The argument is a file matching pattern (similar to a regular expression) that matches the file path (including the file name), but can also specify a specific file path. When there are multiple matching patterns, this parameter can be an array.

  • Options: This parameter is optional. Usually, this parameter is not required.

Gulp uses the Node-glob module internally to implement its file matching function. We can use the following special characters to match the file we want:

# describe
* Matches zero or more characters in the file path, but does not match path delimiters/, unless the path separator appears at the end.
** To match zero or more directories and their subdirectories in a file path, it needs to appear alone, that is, it cannot have anything else around it. If it appears at the end, it also matches the file.
? Matches a single character in a file path (does not match path delimiters)
! The not

For more glob matching rules, see here >>

2. gulp.dest()

Output data stream to destination path in the following syntax:

gulp.dest(path[, options])
Copy the code

Parameter interpretation

  • path: indicates the path for writing files
  • options: is an optional argument object, usually not needed

3. gulp.task()

This method is used to define tasks with the syntax:

gulp.task([taskName], taskFunction)
Copy the code

Note: this API is no longer recommended. It is now mainly used to export task functions directly to files, see here >>

This task can be accessed through the Series, Parallel, and lastRun apis:

# 1. Sequential executiongulp.series(... tasks)# 2. Parallel executiongulp.parallel(... tasks)# 3. Execute last
gulp.lastRun(task, [precision])
Copy the code

4. gulp.watch()

Listen on globs and run tasks when changes occur. Tasks are handled in unison with the rest of the task system.

watch(globs, [options], [task])
Copy the code

Parameter interpretation

  • Globs: For the file matching pattern to be monitored, the rules and usage are the same as glob in the gulp.src() method.

  • Options: Indicates an optional configuration object and is not usually used.

  • Task: task function

gulp.watch("./src/js/*.js", gulp.parallel("handleJS"));
Copy the code

4. Initial experience

1. Basic usage

① Create a project

$ mkdir hello-gulp && cd hello-gulp && npm init -y
Copy the code

(2) Installation dependency

$ npm install gulp --save-dev
Copy the code

View version:

$ ./node_modules/.bin/gulp --version
CLI version: 2.3.0
Local version: 4.0.2
Copy the code

③ Create the gulpfile file

Create gulpfile.js in the root directory and create the task:

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

// task a
const a = (done) = > {
  setTimeout(() = > {
    console.log('Task a is complete! ');
    done();
  }, 1000);
};

// task b
const b = (done) = > {
  setTimeout(() = > {
    console.log('Task b is complete! ');
    done();
  }, 1000);
};

// task c
const c = (done) = > {
  setTimeout(() = > {
    console.log('Task c is complete! ');
    done();
  }, 1000);
};

// -- default task
exports.default = series;
// -- Execute tasks sequentially, first a, then B, then C
exports.series = series(a, b, c);
// -- Execute a, B, and C simultaneously
exports.parallel = parallel(a, b, c);
Copy the code

Tip: Series () and parallel() can be nested to any depth. With these two functions, build tasks can be permutations and combinations to meet a variety of complex build requirements.

④ Running Tasks

Next, we execute the gulP task:

$ ./node_modules/.bin/gulp # execute default task
$ ./node_modules/.bin/gulp series Execute the series task
$ ./node_modules/.bin/gulp parallel # Execute parallel task
Copy the code

2. File operations

Gulp exposes SRC () and dest() methods for handling files stored on the computer. During code build, you need to write the source file to the target directory.

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

exports.default = () = > {
  // Copy the index.js file from SRC /app to dist/app
  return src('src/app/index.js', { base: 'src' }).pipe(dest('dist'));
};
Copy the code

Five, the plug-in

1. Plug-in mechanism

The gulp internal implementation uses three SDKS:

  • undertaker: is used to implement gulP subtask flow management
  • vinyl-fs:.srcThe interface can match a file wildcard and convert the matched file toVinyl Stream(flow),gulpThe idea is that everything flows.
  • glob-watcher: Monitors file flow changes

The core is to convert a file to a Stream and then operate on the Stream.

So gulp uses the concept of pipe, which means that it flows along the pipe, and we can also understand gulp plugins, which have a filter station in the middle of the pipe to filter the flow.

2. Common plug-ins

  • Gulp-rev: adds a hash value to the static resource file name and generates a map file. When the file content is changed, the hash value of the packaged file name is automatically changed and the map file is automatically updated
  • gulp-rev-collector: In an HTML file based on the generated map fileImport the corresponding CSS/JS file
  • Del: deletes a file
  • Browser-sync: development server
  • Gulp-rename: rename a file
  • Gulp-less: compiles less
  • Gulp-sass: compiles sass
  • Gulp-postcss: Handles CSS, built-in plug-ins can compress (cssnano), inject prefixes (autoprefixer), remove excess code (purgecss)
  • Gulp-babel: Compile ECMAScript
  • Gulp-uglify: Compressed JavaScript
  • Gulp-htmlmin: compressed HTML
  • Gulp-imagemin: Compressed image
  • Vinyl-paths: Manipulating files in pipes (e.g. deleting files in pipes)
  • Gulp-cache: cache to avoid repeated compression of images
  • Gulp-load-plugins: plug-in loading
  • Gulp-if: flow control (equivalent to the if statement in JavaScript)
  • Gulp-concat: file merge
  • Gulp-filter: indicates file filtering

Six, Gulp actual combat

Install dependencies:

#general
$ npm install gulp gulp-rename gulp-load-plugins del browser-sync --save-dev
#style
$npm install gulp-postcss cssnano autoprefixer @fullhuman/postcss-purgecss gulp-less --save-dev
#The script
$ npm install gulp-babel @babel/core @babel/cli @babel/preset-env gulp-uglify --save-dev 
#The template
$ npm install gulp-htmlmin --save-dev 
#The picture
$NPM install [email protected] - save - dev
Copy the code

Configuration code:

/* * @Author: Lee * @Date: 2021-12-26 01:56:07 * @LastEditors: Lee * @LastEditTime: 2021-12-26 18:07:45 */

// -- Import the module
const { src, dest, parallel, series, watch } = require('gulp');
const browserSync = require('browser-sync');
const bs = browserSync.create();
const del = require('del');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const purgecss = require('@fullhuman/postcss-purgecss');
const$=require('gulp-load-plugins') ();// -- clear the file
const clean = () = > {
  return del(['dist']);
};

// -- Services & hot updates
const serve = () = > {
  // watch(monitored file, corresponding task)
  watch('src/index.html', html);
  watch('src/**/*.less', style);
  watch('src/**/*.js', script);
  watch('src/images/**', image);
  // Initialize the service
  bs.init({
    notify: false.// Disable the browserSync Connected dialog box in the upper right corner of the browser
    files: 'dist/**'.// Monitor changes to files under DIST and update them in real time on the browser
    server: {
      baseDir: './dist'.// Specify the directory in which the service is started
    },
    port: 5000}); };// -- handle styles
const style = () = > {
  var plugins = [
    autoprefixer({ overrideBrowserslist: ['last 2 version'] }),
    cssnano(),
    purgecss({
      content: ['./src/**/*.html'],}),];return src('src/styles/*.less', { base: 'src' })
    .pipe($.less())
    .pipe($.postcss(plugins))
    .pipe($.rename({ extname: '.min.css' }))
    .pipe(dest('dist'));
};

// -- process the script
const script = () = > {
  return src('src/**/*.js')
    .pipe(
      $.babel({
        presets: ['@babel/preset-env'],
      })
    )
    .pipe($.uglify())
    .pipe($.rename({ extname: '.min.js' }))
    .pipe(dest('dist'));
};

// -- process the template
const html = () = > {
  return src('src/**/*.html')
    .pipe(
      $.htmlmin({
        collapseWhitespace: true.// Remove unnecessary blank lines and whitespace between labels
        minifyCSS: true.// Compress THE CSS code in HTML
        minifyJS: true.// Compress the JS code in HTML
      })
    )
    .pipe(dest('dist'));
};

// -- process the image
const image = () = > {
  return src('src/images/**', { base: 'src' })
    .pipe($.imagemin())
    .pipe(dest('dist'));
};

const build = series(clean, parallel([style, script, html, image]));
const dev = series(build, serve);

module.exports = {
  build,
  dev,
  serve,
};

Copy the code

Seven, expand

To handle caching, add hash values, see here >>