工程化(三)- Gulp

195 阅读3分钟

Gulp

  • 基本使用(gulp当中的任务都是异步任务)
// // 导出的函数都会作为 gulp 任务
// exports.foo = () => {
//   console.log('foo task working~')
// }

// gulp 的任务函数都是异步的
// 可以通过调用回调函数标识任务完成
exports.foo = done => {
  console.log('foo task working~')
  done() // 标识任务执行完成
}

// default 是默认任务
// 在运行是可以省略任务名参数
exports.default = done => {
  console.log('default task working~')
  done()
}

// v4.0 之前需要通过 gulp.task() 方法注册任务
const gulp = require('gulp')

gulp.task('bar', done => {
  console.log('bar task working~')
  done()
})

  • 创建组合任务
const { series, parallel } = require('gulp')

const task1 = done => {
  setTimeout(() => {
    console.log('task1 working~')
    done()
  }, 1000)
}

const task2 = done => {
  setTimeout(() => {
    console.log('task2 working~')
    done()
  }, 1000)  
}

const task3 = done => {
  setTimeout(() => {
    console.log('task3 working~')
    done()
  }, 1000)  
}

// 让多个任务按照顺序依次执行
exports.foo = series(task1, task2, task3)

// 让多个任务同时执行
exports.bar = parallel(task1, task2, task3)

  • 异步任务的三种方式
  • Gulp文件操作API
const { src, dest } = require('gulp')
const cleanCSS = require('gulp-clean-css')
const rename = require('gulp-rename')

exports.default = () => {
  return src('src/*.css')
    .pipe(cleanCSS())
    .pipe(rename({ extname: '.min.css' }))
    .pipe(dest('dist'))
}

Gulp 自动化构建案例

  • 样式编译
// 样式编译
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })  // base 基准目录
    .pipe(plugins.sass({ outputStyle: 'expanded' })) // outputStyle: 'expanded' 完全展开
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}
  • 脚本编译
// 脚本编译
const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}
  • 页面模板编译
// 页面模板编译
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}
  • 图片转换
// 图片转换
const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}
  • 字体文件转换
// 字体文件转换
const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}
  • 其他文件(public文件拷贝)
// public目录文件拷贝
const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}
  • 文件清除
// 文件清除
const clean = () => {
  return del(['dist', 'temp']) // del是外部包
}
  • 自动加载插件 gulp-load-plugins

所有插件都会成为这个对象的属性 gulp-sass plugins.sass

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
  • 热更新开发服务器
// 热更新开发服务器
const serve = () => {
  // 监视文件变化自动重新构建
  // 可能由于swig模板引擎缓存的机制导致页面没有发生变化,可将swig选项中的cache设置为false,具体参考源代码72行
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)
  // watch('src/assets/images/**', image)
  // watch('src/assets/fonts/**', font)
  // watch('public/**', extra)
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload) // bs.reload 自动更新浏览器

  // 初始化web服务器
  bs.init({
    notify: false, // 关闭提升
    port: 2080, // 默认端口3000
    // open: false, // 自动打开浏览器,默认true
    // files: 'dist/**', // browser-sync启动后监听的文件
    server: {
      baseDir: ['temp', 'src', 'public'], // 网页根目录  添加src,public是为了提升开发阶段的构建效率
      routes: {
        '/node_modules': 'node_modules'  // 优先匹配 路由映射
      }
    }
  })
}
  • useref 文件引用处理
// useref 文件引用处理
const useref = () => {
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    // html js css
    .pipe(plugins.if(/\.js$/, plugins.uglify())) // 压缩js
    .pipe(plugins.if(/\.css$/, plugins.cleanCss())) // 压缩css
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({ // 压缩html
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest('dist'))
}
  • 任务组合
// src目录下任务组合
const compile = parallel(style, script, page)

// 上线之前执行的任务
const build =  series(
  clean,
  parallel(
    series(compile, useref),
    image,
    font,
    extra
  )
)

// 开发任务组合
const develop = series(compile, serve)

// 导出任务
module.exports = {
  clean,
  build,
  develop
}
  • 补充
    • 导出任务,包装任务执行(package.json中scripts)
    • 封装自动化构建工作流
  • 目录结构