Gulp 入门教程

788 阅读7分钟

1.什么是gulp

Gulp是一个基于Node.js的自动化构建工具,用于前端项目的构建和开发流程的优化。通过Gulp,可以自动完成文件的压缩、合并、重命名、文件监听、浏览器自动刷新等任务,提高开发效率和代码质量。

2. gulp特点

  1. 简单易用:Gulp的API简单易懂,上手容易,学习曲线较低。
  2. 插件丰富:Gulp的插件生态非常丰富,可以满足各种不同的开发需求。
  3. 高效性能:Gulp采用了流式处理机制,可以在构建过程中尽可能减少中间文件的生成,提高构建效率。
  4. 可定制性强:Gulp的任务可以自由组合,可以根据项目需求进行灵活配置。

3. gulp常用用途

使用Gulp,可以轻松完成如下任务:

  1. 压缩CSS、JavaScript、HTML等文件。
  2. 合并多个CSS、JavaScript等文件为一个文件。
  3. 对图片进行压缩和优化。
  4. 实现浏览器自动刷新。
  5. 实时监控文件变化,并自动执行相应的任务。
  6. 在构建过程中使用sourcemaps追踪代码。
  7. 自定义任务,满足项目特定的需求。

4. gulp安装及运行

安装 gulp 命令行工具

最新版本的gulp是4.x,和之前的3.x的gulp有所不同,把cli分离出去了,所以需要单独安装gulp-cli。

npm install --global gulp-cli

创建项目目录并创建 package.json 文件

npx mkdirp my-project
cd my-project
npm init

安装 gulp,作为开发时依赖项

npm install --save-dev gulp

检查 gulp 版本

gulp --version

Untitled.png

创建gulpfile.js文件

在项目根目录下创建一个名为 gulpfile.js 的文件

// gulpfile.js
function defaultTask(cb) {
    // place code for your default task here
    cb();
}
exports.default = defaultTask

测试

gulp

Untitled 1.png 默认任务(task)将执行,因为任务为空,因此没有实际动作。如果gulp执行不成功 可能是node版本与gulp 版本未对应

gulp 和 Node.js 版本对应关系

  • gulp 4.x: 支持 Node.js 16.x.x
  • gulp 3.x: 支持 Node.js 10.x.x

5. gulp常用API

5.1 gulp.src(globs, [options])

输出(Emits)符合所提供的匹配模式(glob)或者匹配模式的数组(array of globs)的文件。 将返回一个虚拟文件对象( [Vinyl files](https://github.com/wearefractal/vinyl-fs) )的 [stream](http://nodejs.org/api/stream.html) 它可以被 [piped](http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options) 到别的插件中,这个虚拟文件对象中存储着原始文件的路径、文件名、内容等信息。

gulp.src还可以接受一个选项对象作为第二个参数,以指定如何处理文件流。 选项对象中最常用的选项是base,它指定将要处理的文件路径的基准目录,以便在后续的Gulp任务中能够保持文件路径的结构 例如:

 
gulp.src('app/**/*.js', { base: 'app' }).pipe(gulp.dest('dist'));

上面例子会将app路径下的所有js文件写入到dist中( dist/**/*.js ) 中间没有app这层级路径

5.2 gulp.dest(directory, [options])

将流中的文件写入到指定的文件夹中,并返回一个可读流以便后续的 Gulp 操作。

const gulp = require('gulp');
const uglify = require('gulp-uglify');

gulp.task('compress', function() {
  return gulp.src('src/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist/'));
});

在上面的示例中**.pipe(gulp.dest('dist'))** 将经过压缩的文件写入到 **dist**文件夹中,并返回一个可读流以供其他 Gulp 操作使用。

5.3 pipe

是将一个 gulp 插件的输出连接到另一个 gulp 插件的输入的方法。是一种在 gulp 中处理文件流的机制。

在 Gulp 中,通常会创建一个任务(task),用于指定需要对哪些文件进行处理,并使用一个或多个 Gulp 插件来处理这些文件。在处理文件时,可以通过 pipe 方法将多个插件连接起来,形成一个处理文件的管道,以实现逐步处理文件的目的。

例如,假设我们有一个名为 "scss" 的任务,需要将 SCSS 文件编译成 CSS 文件,并将编译后的文件保存到指定目录中。在 gulp 中,可以通过以下方式来实现这个任务:

const gulp = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssnano = require('gulp-cssnano');

gulp.task('scss', function() {
  return gulp.src('src/scss/*.scss')
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(cssnano())
    .pipe(gulp.dest('dist/css'));
});

5.4 gulp.watch(glob [, options], tasks)

用于监视指定的文件,并在文件发生变化时自动执行相应的任务。

gulp.watch('src/js/*.js', ['js']);
gulp.watch(['src/css/*.css', 'src/sass/**/*.scss'], ['css']);

glob 是需要监听的文件的路径模式

options: 一个可选的对象,用于配置监视行为。它可以包含以下属性:

  • cwd: 指定相对路径的基准目录,默认为当前工作目录。
  • ignoreInitial: 指定是否在监视开始时执行一次任务,默认为**false**。
  • events: 一个字符串或字符串数组,用于指定要监视的事件类型,默认为**['add', 'change', 'unlink']**,即文件新增、文件变化和文件删除。
  • delay: 指定延迟多少毫秒后执行任务,默认为200毫秒。

tasks: 一个字符串或字符串数组,用于指定要执行的任务。

5.5 gulp.series(…tasks)

series 是用于按顺序运行多个任务的方法。当需要在 Gulp 中运行多个任务时,可以使用 series 方法将它们连接起来,以确保它们按照指定的顺序依次运行。

例如,假设我们有一个名为 build的任务,需要先执行 clean 任务清除旧文件,然后执行 scss 任务将 SCSS 文件编译成 CSS 文件,最后执行 js 任务将 JavaScript 文件压缩成单个文件

const { src, dest, series } = require('gulp');
const del = require('del'); // del 7.0.0版本不支持commonJS
const sass = require('gulp-sass')(require('sass'));
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');

// 清除旧文件
function clean() {
   return del(['dist']);
}

// 编译 SCSS 文件
function scss() {
    return src('src/scss/*.scss')
        .pipe(sass())
        .pipe(dest('dist/css'));
}

// 压缩 JavaScript 文件
function js() {
    return src('src/js/*.js')
        .pipe(uglify())
        .pipe(concat('app.min.js'))
        .pipe(dest('dist/js'));
}

// 将多个任务连接起来按顺序执行
exports.default = series(clean, scss, js)

5.6 gulp.parallel()

parallel 是用于并行运行多个任务的方法。当需要同时运行多个任务时,可以使用 parallel 方法将它们连接起来,以确保它们同时运行。

例如,假设我们有一个名为 watch 的任务,需要同时监视 SCSS 文件和 JavaScript 文件的变化,并在文件变化时重新编译和压缩文件

const {
    src, dest, task, parallel, series, watch
} = require('gulp');
const browserSync = require('browser-sync').create();
const sass = require('gulp-sass')(require('sass'));
const uglify = require('gulp-uglify');

// 编译 SCSS 文件
function scss() {
    return src('src/scss/*.scss')
        .pipe(sass())
        .pipe(dest('dist/css'))
        .pipe(browserSync.stream());
}

// 压缩 JavaScript 文件
function js() {
    return src('src/js/*.js')
        .pipe(uglify())
        .pipe(dest('dist/js'))
        .pipe(browserSync.stream());
}

// 刷新浏览器
function reload(done) {
    browserSync.reload();
    done();
}

// 监视 SCSS 文件的变化并自动重新编译
function watchScss() {
    return watch('src/scss/*.scss', series(scss, reload));
}

// 监视 JavaScript 文件的变化并自动压缩
function watchJs() {
    return watch('src/js/*.js', series(js, reload));
}

// 将多个任务连接起来并行执行
task('watch', parallel(watchScss, watchJs));

在这个任务中,首先通过定义 watchScss、watchJs、scss、js 和 reload 五个任务来分别实现监视 SCSS 文件、监视 JavaScript 文件、编译 SCSS 文件、压缩 JavaScript 文件和刷新浏览器的功能。然后,通过使用 gulp.parallel 方法将监视 SCSS 文件和监视 JavaScript 文件的任务连接起来,并行执行,以实现自动重新编译和刷新浏览器的功能。

6. 拆分gulp配置文件

大型项目中**gulpfile.js**文件可能会变得越来越复杂,难以维护。为了解决这个问题,我们可以将 **gulpfile.js**文件拆分成多个文件,每个文件负责一个或多个任务的定义和配置。

目录结构
my-gulp/
  tasks/
		js.js
    images.js
  gulpfile.js

// images.js 文件:
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');

gulp.task('images', function() {
  return gulp.src('src/images/*')
    .pipe(imagemin())
    .pipe(gulp.dest('dist/images'));
});
// js.js 文件
const gulp = require('gulp');
const uglify = require('gulp-uglify');

gulp.task('js', function() {
  return gulp.src('src/js/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist/js'));
});
// gulpfile.js 文件
const gulp = require('gulp');
const requireDir = require('require-dir');

requireDir('./tasks');
gulp.task('default', gulp.series('js','images'));

这种拆分方式可以使 **gulpfile.js**文件变得更加清晰和易于维护。当需要添加或修改任务时,只需要编辑对应的文件即可,而不需要在一个庞大的文件中查找和编辑。