简介

gulp 是前端自动化打包构建工具,所谓打包可以理解为把文件压缩, 整合, 移动, 混淆。gulp 是一种基于流的打包构建工具。

文档:https://www.gulpjs.com.cn/docs/api/concepts/

使用 gulp,首先要全局安装gulp,全局安装只是可以使用其命令

# 安装
npm install --global gulp
# 卸载
npm uninstall --global gulp
# 查看版本
gulp -v

也可以局部安装,通过scripts运行。

常用 API

  1. task()

    创建一个基于流的任务

    gulp.task('htmlHandler', function () {
      // 找到 html 源文件, 进行压缩, 打包, 放入指定目录
    })
  2. src()

    找到源文件

    // 找到指定一个文件
    gulp.src('./a/b.html')
    
    // 找到指定目录下, 指定后缀的文件
    gulp.src('./a/*.html')
    
    // 找到指令目录下的所有文件
    gulp.src('./a/**')
    
    // 找到 a 目录下所有子目录里面的所有文件
    gulp.src('./a/** /*')
    
    // 找到 a 目录下所有子目录里面的所有 .html 文件
    gulp.src('./a/** /*.html')
  3. dest()

    把一个内容放入指定目录内

    gulp.dest('./abc')
  4. watch()

    监控指定目录下的文件, 一旦发生变化, 从新执行后面的任务

    gulp.watch('./src/pages/*.html', htmlHandler)
  5. series()

    逐个执行多个任务, 前一个任务结束, 第二个任务开始

    gulp.series(任务1, 任务2, 任务3, ...)
  6. parallel()

    并行开始多个任务

    gulp.parallel(任务1, 任务2, 任务3, ...)
  7. pipe()

    管道函数,所有的 gulp API 都是基于流。接收当前流, 进入下一个流过程的管道函数

    gulp.src().pipe(压缩任务).pipe(转码).pipe(gulp.dest('abc'))

常用插件

  1. gulp-cssmin

    npm i gulp-cssmin -D

    导入以后得到一个处理流文件的函数

    https://www.npmjs.com/package/gulp-cssmin

  2. gulp-autoprefixer

    npm i gulp-autoprefixer -D

    导入以后得到一个处理流文件的函数,直接再管道函数里面使用, 需要传递参数

    {
      browsers: [要兼容的浏览器]
    }

    https://www.npmjs.com/package/gulp-autoprefixer

  3. gulp-sass

    编译scsssass文件为css文件

    npm i gulp-sass -D

    导入后直接使用即可

  4. gulp-less

    gulp-sass类似,编译less文件为css文件

  5. gulp-uglify

    压缩js文件

    npm i -D gulp-uglify

    此压缩不可以压缩ES6,因此如果有 ES6 代码,需要先转为ES5

  6. gulp-babel

    专门进行 ES6 转 ES5 的插件。

    yarn add gulp-babel @babel/core  @babel/preset-env -D

    gulp-babel 有两个版本,8 主要用于 gulp4 中,7 主要用于 gulp3 中。默认安装最新版。

  7. gulp-htmlmin

    压缩 html

    npm i -D gulp-htmlmin
  8. del

    删除文件目录

    yarn add del -D
  9. gulp-connect

    启动一个服务器,用于自动构建。

    yarn add gulp-connect -D
  10. gulp-pug

    编译pughtml文件

    yarn add gulp-pug -D
  11. gulp-concat

    合并js/css文件

    yarn add gulp-concat -D

常用示例

构建 JS

将含有 ES6 代码的 js 文件合并并压缩。

安装插件

yarn add gulp-concat gulp-uglify gulp-rename gulp-babel @babel/core  @babel/preset-env -D

编写构建任务

var gulp = require('gulp')
var concat = require('gulp-concat')
var uglify = require('gulp-uglify')
var rename = require('gulp-rename')
var babel = require('gulp-babel')

const js = () => {
  return (
    gulp
      .src('src/js/*.js')
      // .pipe(concat('build.js')) // 参数为合并完的文件名
      .pipe(
        babel({
          presets: ['@babel/env']
        })
      )
      // .pipe(gulp.dest('dist/js/')) // 临时输出文件到本地
      .pipe(uglify()) // 压缩文件
      // .pipe(rename({ suffix: '.min' })) // 重命名
      .pipe(gulp.dest('dist/js/')) // 输出文件
  )
}

exports.default = gulp.parallel(js)

css、less、scss、sass

安装插件

yarn add gulp-less gulp-sass gulp-clean-css gulp-concat del gulp-rename  -D

编写任务代码

// 编译scss
const scssTask = () => {
  return gulp
    .src('./src/scss/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('./src/css/scss/'))
}
// 编译less
const lessTask = () => {
  return gulp
    .src('./src/less/*.less')
    .pipe(less())
    .pipe(gulp.dest('./src/css/less/'))
}
// 删除 less 和 scss 产生的文件夹
const delLessScss = () => {
  return del(['./src/css/less/', './src/css/scss/'])
}
// 处理css文件
const cssTask = async () => {
  return gulp
    .src('./src/css/**/*.css')
    .pipe(concat('build.css'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(cssClean({ compatibility: 'ie8' }))
    .pipe(gulp.dest('dist/css/'))
}

exports.default = gulp.series(
  gulp.parallel(scssTask, lessTask),
  cssTask,
  delLessScss
)

编译 pug、压缩 html

安装插件

yarn add gulp-htmlmin gulp-pug del -D

编写压缩任务

// 删除dist目录
const delDest = () => {
  return del(['./dist/'])
}

// 编译pug任务
const pugTask = () => {
  return gulp.src('./src/pug/*.pug').pipe(pug()).pipe(gulp.dest('./dist/'))
}
// 压缩html
const htmlminTask = () => {
  return gulp.src('./dist/**/*.html').pipe(
    htmlmin({
      removeComments: true, //清除HTML注释
      collapseWhitespace: true, //压缩HTML
      collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input checked />
      removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
      removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
      removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
      minifyJS: true, //压缩页面JS
      minifyCSS: true //压缩页面CSS
    })
  )
}

exports.default = gulp.series(delDest, pugTask, htmlminTask)

自动化示例

/**
 * @description:
 * @author: 小康
 * @url: https://xiaokang.me
 * @Date: 2020-12-26 17:11:49
 * @LastEditTime: 2020-12-26 17:11:49
 * @LastEditors: 小康
 */
var gulp = require('gulp')

var pug = require('gulp-pug')
var htmlmin = require('gulp-htmlmin')
var less = require('gulp-less')
var sass = require('gulp-sass')
var cssClean = require('gulp-clean-css')

var uglify = require('gulp-uglify')
var babel = require('gulp-babel')

var concat = require('gulp-concat')
var rename = require('gulp-rename')
var del = require('del')

var connect = require('gulp-connect')
var open = require('open')
// 删除dist目录
const delDest = () => {
  return del(['./dist/'])
}
// 删除 less 和 scss 产生的文件夹
const delLessScss = () => {
  return del(['./src/css/less/', './src/css/scss/'])
}

// 编译pug任务
const pugTask = () => {
  return gulp
    .src('./src/pug/*.pug')
    .pipe(pug())
    .pipe(gulp.dest('./dist/'))
    .pipe(connect.reload())
}
// 压缩html
const htmlminTask = () => {
  return gulp
    .src('./dist/**/*.html')
    .pipe(
      htmlmin({
        removeComments: true, //清除HTML注释
        collapseWhitespace: true, //压缩HTML
        collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input checked />
        removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
        removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
        removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
        minifyJS: true, //压缩页面JS
        minifyCSS: true //压缩页面CSS
      })
    )
    .pipe(connect.reload())
}

// 编译scss
const scssTask = () => {
  return gulp
    .src('./src/scss/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('./src/css/scss/'))
    .pipe(connect.reload())
}
// 编译less
const lessTask = () => {
  return gulp
    .src('./src/less/*.less')
    .pipe(less())
    .pipe(gulp.dest('./src/css/less/'))
    .pipe(connect.reload())
}

// 处理css文件
const cssTask = async () => {
  return gulp
    .src('./src/css/**/*.css')
    .pipe(concat('build.css'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(cssClean({ compatibility: 'ie8' }))
    .pipe(gulp.dest('dist/css/'))
    .pipe(connect.reload())
}

// 编译js
const jsTask = () => {
  return gulp
    .src('src/js/*.js')
    .pipe(
      babel({
        presets: ['@babel/env']
      })
    )
    .pipe(uglify()) // 压缩文件
    .pipe(gulp.dest('dist/js/')) // 输出文件
    .pipe(connect.reload())
}
const server = () => {
  gulp.watch(['src/scss/**/*.scss'], gulp.series(scssTask))
  gulp.watch(['src/less/**/*.less'], gulp.series(lessTask))
  gulp.watch(['src/css/**/*.css'], gulp.series(cssTask))
  gulp.watch(['src/pug/**/*.pug'], gulp.series(pugTask))
  gulp.watch(['src/js/**/*.js'], gulp.series(jsTask))
  connect.server({
    root: 'dist/',
    livereload: true,
    port: 5000
  })
  open('http://localhost:5000/')
}

gulp.task(
  'build',
  gulp.series(
    delDest,
    pugTask,
    htmlminTask,
    scssTask,
    lessTask,
    cssTask,
    jsTask,
    delLessScss
  )
)
gulp.task('server', gulp.series('build', server))

关于任务执行顺序

同步执行即按顺序执行

exports.default = gulp.series('js', ['less', 'css'])

异步执行即不会按照顺序去执行

exports.default = gulp.parallel('js', ['less', 'css'])

这两个方法支持任意层次的嵌套。

exports.default = gulp.parallel('js', gulp.series(['less', 'css']))