gulp的基本使用方式

时间:2021-2-20 作者:admin

仅作为拉勾大前端的学习记录

gulp的基本使用

  • yarn init --yes 初始化package.json 文件
  • yarn add gulp --dev安装gulp包
  • 创建gulpfile.js 作为gulp 的入口文件
// gulpfile.js文件是 gulp的入口文件
exports.foo = function(done){
  console.log("hello foo")
  done()
}
// 默认任务
exports.default = function(done){
  console.log("hello default")
  done()
}

gulp的组合任务

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

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

exports.default = series(task1, task2) // 串行任务执行
exports.bar = parallel(task1, task2) // 并行任务执行

gulp的异步任务

const fs = require('fs');

// 第一种直接调用done
exports.callback = done => {
  console.log('callback task');
  done();
}

exports.callback_error = done => {
  console.log('callback_error task');
  done(new Error('callback_error task failed'));
}
// 第二种promise的方式
exports.promise = () =>{
  console.log('promise task')
  return Promise.resolve()
}

const timeout = time =>{
  return new Promise((resolve) => {
    setTimeout((resolve,time))
  })
}

exports.async = async ()=>{
  await timeout(1000)
  console.log('async task')
}
// 第三种 添加实例方法,调用done
exports.stream = () =>{
  const readStream = fs.createReadStream('package.json')
  const writeStream = fs.createWriteStream('temp.txt')
  readStream.pipe(writeStream)
  // return readStream
  // 或者写成
  readStream.on('end',()=>{
      done()
  })
}

gulp构建过程核心工作原理

const fs = require('fs');
const { Transform } = require('stream');

exports.default = () =>{
  // 创建文件读取流
  const read = fs.createReadStream('normalize.css')
  // 文件写入流
  const write = fs.createWriteStream('normalize.min.css')

  // 文件转换流
  const transform = new Transform({
    transform: (chunk,encoding,callback) => {
      // 核心转换过程
      // chunk读取流中读取到的内容(Buffer),所以需要toString拿到文件内容
      const input = chunk.toString()
      const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')
      callback(null, output)
    }
  })



  // 把读取出来的文件流导入写入文件流
  read
    .pipe(transform)
    .pipe(write)

  return read
}

Gulp文件操作API

读取流 — 转换流 — 写入流

const { src, dest } = require('gulp')
const cleanCss = require('gulp-clean-css') // css的转换流
const rename = require('gulp-rename')

exports.default = done =>{
  // src读取流,dest写入流,return出去让gulp知道此任务已完成
  return src('src/*.css')
    .pipe(cleanCss()) // 转换css
    .pipe(rename({ extname: '.min.css' }))
    .pipe(dest('dist'))
}

Gulp转换项目的案例

// 实现这个项目的构建任务
// watch自动监听通配符,根据文件更新来决定是否要执行某个人物
const { src, dest, parallel, series, watch } = require('gulp')

const del = require('del')
const browserSync = require('browser-sync') // 依靠这个模块加载开发服务器

const loadPlugins = require('gulp-load-plugins')

const plugins = loadPlugins() //loadPlugins导出的是一个方法,通过方法得到plugins
const bs = browserSync.create() // 用提供的creat()方法创建服务器

const data = {
  menus: [],
  pkg: require('./package.json'),
  date: new Date()
}

const clean = ()=>{
  return del(['dist','temp'])
}

const page = ()=>{
  // swig 为模板引擎的转换插件
  // 原来的模板用到了一些数据标记,去标记开发中可能变化的东西
  // 通过swig的data参数,把设定的data传入到模板中
  return src('src/*.html', { base: 'src'})
    .pipe(plugins.swig({ data }))
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true})) // 内部以流的方式推到浏览器,
}

const script = ()=>{
  // gulp-babel只是帮你唤起@babel/core的转换过程
  // preset-env会帮助转换所有的es6模块,他是可以转换所有新特性的集合
  return src('src/assets/scripts/*.js', { base: 'src' })
  .pipe(plugins.babel({presets: ['@babel/preset-env']}))
  .pipe(dest('temp'))
  .pipe(bs.reload({stream: true})) // 内部以流的方式推到浏览器,
}

const style = ()=>{
  // outputStyle: 'expanded' 是指定转换后结束括号的位置
  return src('src/assets/styles/*.scss', { base: 'src' })
  .pipe(plugins.sass({ outputStyle: 'expanded'}))
  .pipe(dest('temp'))
  .pipe(bs.reload({stream: true})) // 内部以流的方式推到浏览器,
}

const image = ()=>{
  // imagemin插件用于图片的压缩
  return src('src/assets/images/**', { base: 'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const font = ()=>{
  // imagemin可以压缩字体文件中的svg
  return src('src/assets/fonts/**', { base: 'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

// 处理其他文件
const extra = ()=>{
  return src('public/**',  { base: 'public' })
    .pipe(dest('dist'))
}

const serve = ()=>{
  // watch下面监听src的变化
  watch('src/*.html',page)
  watch('src/assets/scripts/*.js',script)
  watch('src/assets/styles/*.scss',style)

  // 只是去监听iamge,font,public文件的变化,不去构建
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ],bs.reload)

  // 初始化服务器配置
  bs.init({
    port: '2080', // 服务器端口号
    // browser-sync 启动后用来去监听的路径通配符
    // files:'temp/**',
    server: {
      // 请求过来后先从[0]目录下面去找,如果找不到就去src下面查找...
      baseDir: ['temp','src','public'],
      // 优先于baseDir的配置
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const useref = () =>{
  // useref 自动处理构建注释
  return src('temp/*.html', {base: 'temp'})
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    // 希望对生成的文件进行压缩,因为读取流中有三个不同的文件,希望对不同文件进行不同操作
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    // 可以在方法中配置一些自定义的选项,下面的选项是压缩空白字符,压缩行内css,压缩w文件内js
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({ 
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest('dist'))
}

// 使用parallel把这些任务通过并行的方式导出
const compile = parallel(page,script,style )

// 一般 iamge,font public 的任务,项目开发阶段不会让他自动化构建,只是再发布的时候去构建项目

const build = series( 
  clean, 
  parallel(
    series(compile,useref),
  image,
  font,
  extra
  ) 
) 

const start = series(compile, serve)

module.exports = {
  build,
  start,
  clean
}
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。