Part2-1-3 自动化构建

Gulp 的基本使用

安装 gulp

yarn add gulp --dev

在项目根目录下创建 gulp入口文件 gulpfile.js

// 实现这个项目的构建任务
exports.foo = done => {
  console.log('foo123')
  done()  // gulp 任务都为异步任务,所以需要调用done函数来标识任务结束
}

// default 为默认任务
exports.default = done => {
  console.log('defalut task')
  done()  // gulp 任务都为异步任务,所以需要调用done函数来标识任务结束
}

 

执行任务命令

yarn gulp foo

 

执行默认任务命令

yarn gulp

 

Gulp 创建组合任务

使用 gulp 的 series、parallel 模块来创建组合任务

series 用来创建串行任务

parallel 用来创建并行任务

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 创建异步任务的几种方式

const fs = require('fs')

// 使用回调函数
exports.callback = done => {
  console.log('callback task')
  done()
}

exports.callback_error = done => {
  console.log('callback task')
  done(new Error('task failed'))
}

// 使用 promise
exports.promise = () => {
  console.log('promise task')
  return Promise.resolve()
}

exports.promise_error = () => {
  console.log('promise task')
  return Promise.reject(new Error('task failed'))
}


// 使用 async await
exports.async = async () => {
  await timeout(1000)
  console.log('async task')
}

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


// 使用 stream
// readStream 有一个 end 的事件,一旦读取的文件流完成后,就会触发end事件,gulp就会知道任务完成了
exports.stream = () => {
  const read = fs.createReadStream('yarn.lock')
  const write = fs.createWriteStream('a.txt')
  read.pipe(write)
  return read
}

 

使用gulp完成代码压缩

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

exports.default = () => {
  // 文件读取流
  const readStream = fs.createReadStream('normalize.css')

  // 文件写入流
  const writeStream = fs.createWriteStream('normalize.min.css')

  // 文件转换流
  const transformStream = new Transform({
    // 核心转换过程
    transform: (chunk, encoding, callback) => {
      const input = chunk.toString()
      const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')
      callback(null, output)
    }
  })

  return readStream
    .pipe(transformStream) // 转换
    .pipe(writeStream) // 写入
}

 

Gulp 文件操作API + 插件的使用

const { src, dest } = require('gulp') // src: 读取流  dest: 写入流
const cleanCSS = require('gulp-clean-css') // 压缩 css文件
const rename = require('gulp-rename') // 写入后的文件重命名

exports.default = () => {
  return src('src/*.css')
    .pipe(cleanCSS())
    .pipe(rename({ extname: '.min.css' })) // extname:重新命名扩展名
    .pipe(dest('dist'))
}

 

样式编译

const { src, dest } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件


// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}

module.exports = {
  style
}

 

脚本编译

安装 babel 依赖  yarn add gulp-bable --dev

安装 babel 核心转换模块  yarn add @babel/core @babel/preset-env --dev

const { src, dest } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法



// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


module.exports = {
  style,
  script 
}

 

页面模板编译

如果页面有使用模板引擎,则要安装 对应的模板引擎转换插件

例如页面使用了 swig, 需要安装 swig 转换插件 yarn add gulp-swig --dev

然后使用 parallel  完成 并行任务

const { src, dest, parallel } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(swig({ data }))
    .pipe(dest('dist'))
}


const compile = parallel(style, script, page)


module.exports = {
  compile
}

 

图片和字体文件的转换

安装图片压缩插件  yarn add gulp-imagemin --dev  此压缩是无损压缩,也可以对字体文件的 svg 文件进行压缩

 

const { src, dest, parallel } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
const imagemin= require('gulp-imagemin')


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(swig({ data }))
    .pipe(dest('dist'))
}


const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}


const compile = parallel(style, script, page, image, font)


module.exports = {
  compile
}

 

public等不需要编译的额外文件的目录下文件构建

建立 build 任务,用 parallel 并行执行任务模块,同时进行 extra, 和compile的任务

const { src, dest, parallel } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
const imagemin= require('gulp-imagemin')


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(swig({ data }))
    .pipe(dest('dist'))
}


const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}


const compile = parallel(style, script, page, image, font)

const build = parallel(compile, extra)


module.exports = {
  build
}

 

文件清除

每次构建项目前,需要先对dist目录进行清除

安装清除插件   yarn add del --dev

由于项目构建前应先清除原有目录文件,所以用 series 串行任务模块,先执行 clean,再执行 build

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


const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
const imagemin= require('gulp-imagemin')


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


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

// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(swig({ data }))
    .pipe(dest('dist'))
}


const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}


const compile = parallel(style, script, page, image, font)

const build = series(clean, parallel(compile, extra))


module.exports = {
  build
}

 

自动加载插件

安装 gulp-load-plugins 可以使用 一些gulp插件,这样就不用再单独安装很多插件  yarn add gulp-load-plugins --dev

const { src, dest, parallel, series } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()


// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


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

// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(plugins.sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data }))
    .pipe(dest('dist'))
}


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'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}


const compile = parallel(style, script, page, image, font)

const build = series(clean, parallel(compile, extra))


module.exports = {
  build
}

 

热更新开发服务器

安装开发服务器模块,支持代码修改后,自动更新到浏览器中,  yarn add browser-sync --dev

const { src, dest, parallel, series } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')

const plugins = loadPlugins()
const bs = browserSync.create()


// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


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

// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(plugins.sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data }))
    .pipe(dest('dist'))
}


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'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const serve = () => {
  bs.init({
    notify: false,  // 关闭提示,以免影响样式调试
    port: 2080, // 默认端口 3000
    // open: false, // 自动打开浏览器设置,默认是 true
    // files: 'dist/**', // 设置让 browser-sync 监听的文件
    server: {
      baseDir: 'dist',
      routes: {  // routes 会先于 baseDir执行
        '/node_modules': 'node_modules'
      }
    }
  })
}


const compile = parallel(style, script, page, image, font)

const build = series(clean, parallel(compile, extra))


module.exports = {
  build,
  serve
}

 

监视变化

引入 gulp 的 watch 模块

在 serve 任务中加入 watch 任务

const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')

const plugins = loadPlugins()
const bs = browserSync.create()


// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


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

// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(plugins.sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}


// defaults: { cache: false } 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data, defaults: { cache: false } }))
    .pipe(dest('dist'))
}


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'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const serve = () => {
  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)
  bs.init({
    notify: false,  // 关闭提示,以免影响样式调试
    port: 2080, // 默认端口 3000
    // open: false, // 自动打开浏览器设置,默认是 true
    // files: 'dist/**', // 设置让 browser-sync 监听的文件
    server: {
      baseDir: 'dist',
      routes: {  // routes 会先于 baseDir执行
        '/node_modules': 'node_modules'
      }
    }
  })
}


const compile = parallel(style, script, page, image, font)

const build = series(clean, parallel(compile, extra))


module.exports = {
  build,
  serve
}

 

构建优化

image,font,public 下的文件不会频繁改动,因此无需在开发的时候实时监听,因为监视更多的文件意味着更大的开销

将 image,font 任务从 compile 任务中取出,在开发阶段中不做编译, 

将image, font 任务放入 build 任务中

增加 develop 任务,使用 series串行模块,先执行 compile 任务,再执行 serve 任务

给 style, script, html 任务 增加 bs.reload({ stream: true }),使得浏览器监听到修改的变化并更新,

stream: true:以流的方式推送给浏览器

const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')

const plugins = loadPlugins()
const bs = browserSync.create()


// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


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

// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(plugins.sass({ outputStyle: 'expanded' })) 
    .pipe(dest('dist'))
    .pipe(bs.reload({ stream: true }))
}


const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
    .pipe(bs.reload({ stream: true }))
}


// defaults: { cache: false } 防止模板缓存导致页面不能及时更新
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data, defaults: { cache: false } }))
    .pipe(dest('dist'))
    .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'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const serve = () => {
  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.init({
    notify: false,  // 关闭提示,以免影响样式调试
    port: 2080, // 默认端口 3000
    // open: false, // 自动打开浏览器设置,默认是 true
    // files: 'dist/**', // 设置让 browser-sync 监听的文件
    server: {
      baseDir: ['temp', 'src', 'public'], // 会从第一个目录寻找,如果没有寻找到,以此向后寻找,image,font在开发阶段就直接用原文件,节省构建速度
      routes: {  // routes 会先于 baseDir执行
        '/node_modules': 'node_modules'
      }
    }
  })
}


const compile = parallel(style, script, page)

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

const develop = series(compile, serve)


module.exports = {
  build,
  develop
}

 

引用文件处理

安装引用依赖插件  yarn add gulp-useref --dev

添加 useref 任务,会将引用的外部依赖文件 写入新建的文件中

要对这些新建的文件进行压缩

安装 html,js,css 的压缩插件   yarn add gulp-htmlmin gulp-uglify gulp-css-clean --dev

安装 gulp-if 插件,针对文件的读取流分别做不同的操作  yarn add gulp-if --dev

将压缩后的文件先放在 release 目录里,防止读取文件在一个目录下会产生冲突

因为多了 release 目录,之前的构建目录需要做调整

将 style, script, page 这三个在开发阶段需要构建的任务,在构建后放入 temp 目录

相应的 useref 任务改成从 temp 目录中读取文件

将 useref 任务 放入 build 任务, compile 任务执行完后,才能执行 useref 任务

const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')

const plugins = loadPlugins()
const bs = browserSync.create()


// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩


// 准备页面模板引擎渲染数据
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


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

// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
    .pipe(plugins.sass({ 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 }))
}


// defaults: { cache: false } 防止模板缓存导致页面不能及时更新
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'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const serve = () => {
  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.init({
    notify: false,  // 关闭提示,以免影响样式调试
    port: 2080, // 默认端口 3000
    // open: false, // 自动打开浏览器设置,默认是 true
    // files: 'dist/**', // 设置让 browser-sync 监听的文件
    server: {
      baseDir: ['temp', 'src', 'public'], // 会从第一个目录寻找,如果没有寻找到,以此向后寻找,image,font在开发阶段就直接用原文件,节省构建速度
      routes: {  // routes 会先于 baseDir执行
        '/node_modules': 'node_modules'
      }
    }
  })
}


const useref = () => {
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true, // 压缩空白符和换行符
      minifyCSS: true, // 压缩css代码
      minifyJS: true // 压缩js代码
    })))
    .pipe(dest('dist')) // 将压缩后的文件先放在 release 目录里
}


const compile = parallel(style, script, page)

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

const develop = series(compile, serve)


module.exports = {
  build,
  develop
}

 

配置启动命令

将 build, develop启动命令配置到 package.json 文件中去

"scripts": {
    "build": "gulp build",
    "develop": "gulp develop"
 }

 

发布并使用模块

发布模块

yarn publish --registry https://registry.yarnpkg.com

 

 

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值