前端学习-Gulp

170 阅读4分钟

Gulp 与 npm scripts

  • Gulp 与 npm scripts 都能够实现自动化构建
  • Gulp 语法简单
    Gulp 语法就是 JavaScript 语法
    npm scripts 语法接近 shell 脚本
  • Gulp 生态完善,构建效率高

基本使用

  • 全局安装 gulp 客户端( npm install -g gulp- cli )
  • 初始化项目(npm init --yes)
  • 安装 gulp 包( npm install gulp -D )
  • 新建 gulpfile 文件 ( gulpfile.js )
  • 在 gulpfile.js 中,创建 gulp 任务
const gulp = require('gulp')

// 创建 gulp 任务
const task1 = (cb) => {
  console.log('Task 1 is running')

  //添加回调方法使函数异步执行
  cb()
}

const task2 = (cb) => {
  console.log('Task 2 is running')

  cb()
}

// 旧版声明任务的语法
gulp.task('task3', (cb) => {
  console.log('Task 3 is running')

  cb()
})

// 导出任务
module.exports = {
  task1,
  default: task2 // 默认任务
}
  • 执行 gulp 任务 ( gulp task-name )

组合任务

  • 并行任务
    gulp.parallel(task1, task2, task3)
  • 串行任务
    gulp.series(task1, task2, task3)
  • 构建组合任务
    gulp.series( 任务1, gulp.parallel( 任务2, 任务3 ), 任务4 )
// 引入 gulp
const gulp = require('gulp')

const task1 = (cb) => {
  setTimeout(() => {
    console.log('Task 1 is running')

    cb()
  }, 1000)
}

const task2 = (cb) => {
  setTimeout(() => {
    console.log('Task 2 is running')

    cb()
  }, 1000)
}

const task3 = (cb) => {
  setTimeout(() => {
    console.log('Task 3 is running')

    cb()
  }, 1000)
}

// 任务的并行执行
exports.p = gulp.parallel(task1, task2, task3)

// 任务的串行执行
exports.s = gulp.series(task1, task2, task3)

文件操作

Gulp 是基于 流 的构建系统

// 引入 gulp
// const gulp = require('gulp')
// 通过 解构 的方式引入函数
const { src, dest } = require('gulp')

// 声明 gulp 任务
const style = () => {
  // 流 就是异步操作
  // return gulp.src('src/styles/main.less', { base: 'src' }).pipe(gulp.dest('dist'))
  return src('src/styles/main.less', { base: 'src' }).pipe(dest('dist'))
}

// 导出任务
module.exports = {
  style
}

构建样式文件

构建样式文件所需插件

  • 将 less 文件,转成 css 文件
    npm i gulp-less -D

  • 压缩 CSS 代码
    npm i gulp-clean-css -D

  • 对文件进行重命名
    npm i gulp-rename -D

CSS hack 与 Autoprefixer

保证 CSS 的兼容性

CSS hack

  • CSS 代码存在兼容性问题
    同一段 CSS 代码,在不同浏览器上的呈现效果不同。
  • 针对不同的浏览器写相应的 CSS 代码
    我们把针对不同的浏览器写相应的 CSS 代码的过程,叫做 CSS hack

属性前缀法

  • user-select 属性可以控制用户能否选中文本( 存在兼容性问题)
  • 给 CSS 属性(user-select),添加浏览器特有的前缀 Autoprefixer 使用 caniuse.com 的数据 来决定哪些属性需要加前缀
// 通过 解构 的方式引入函数
const { src, dest } = require('gulp')
const less = require('gulp-less')
const cleancss = require('gulp-clean-css')
const rename = require('gulp-rename')
const autoprefixer = require('gulp-autoprefixer')

// 声明 gulp 任务
const style = () => {
  // 流 就是异步操作
  return src('src/styles/main.less', { base: 'src' })
    .pipe(less())//将less转换成css
    .pipe(autoprefixer())//css hack
    .pipe(cleancss())//压缩css
    .pipe(rename({ "extname": ".min.css" }))//重命名文件
    .pipe(dest('dist'))
}

// 导出任务
module.exports = {
  style
}

构建脚本文件

所需插件

  • 将 ES6+ 新语法转成 ES5
    gulp-babel
  • 压缩 JS 代码
    gulp-uglify
  • 对文件进行重命名
    gulp-rename
// 通过 解构 的方式引入函数
const { src, dest } = require('gulp')
const rename = require('gulp-rename')
const babel = require('gulp-babel')
const uglify = require('gulp-uglify')

// 声明 gulp 任务

// 声明 脚本 构建任务
const script = () => {
  return src('src/js/main.js')
    .pipe(babel({
      presets: ['babel-preset-env']//将JS转换成ES5的语法
    }))
    .pipe(uglify())//压缩JS文件
    .pipe(rename({ "extname": ".min.js" }))//重命名文件
    .pipe(dest('dist/scripts'))
}

// 导出任务
module.exports = {
  script
}

构建页面( HTML )文件

  • 压缩 HTML 文件
    gulp-htmlmin
// 通过 解构 的方式引入函数
const { src, dest, parallel } = require('gulp')
const htmlmin = require('gulp-htmlmin')

// 声明 gulp 任务

// 声明 页面 的构建任务
const html = () => {
  return src('src/index.html')
    .pipe(htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    }))
    .pipe(dest('dist'))
}

// 组合任务
const build = parallel(style, script, html)

// 导出任务
module.exports = {
  style,
  script,
  html,
  build
}

构建资源(图片)文件

所需插件

  • 压缩图片文件
    gulp-imagemin
// 通过 解构 的方式引入函数
const { src, dest, parallel } = require('gulp')
const imagemin = require('gulp-imagemin')


// 声明 图片 构建任务
const image = () => {
  return src('src/images/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

// 导出任务
module.exports = {
  image
}

文件清除

所需插件

  • 删除文件和目录
    del
// 通过 解构 的方式引入函数
const { src, dest, parallel, series } = require('gulp')
const del = require('del')

// 声明 gulp 任务

// 声明 文件清除 任务
const clean = () => {
  return del(['dist'])
}

// 组合任务
const build = parallel(style, script, html, image)

const dev = series(clean, build)

// 导出任务
module.exports = {
  build,
  dev
}

开发服务器

所需插件

  • 发布 web 服务
    browser-sync
// 通过 解构 的方式引入函数
const { src, dest, parallel, series, watch } = require('gulp')

const browserSync = require('browser-sync')
const bs = browserSync.create()



// 声明 服务发布 任务
const serve = () => {
  // watch(被监视的文件,对应的任务)
  watch('src/index.html', html)
  watch('src/styles/*.less', style)
  watch('src/js/*.js', script)
  watch('src/images/**', image)

  // 初始化服务
  bs.init({
    notify: false,      // 禁用 浏览器 右上角的 browserSync connected 提示框
    files: 'dist/**',   // 监视 dist 下 文件的变化,然后在浏览器上实时更新
    server: {
      baseDir: './dist', // 指定服务启动的目录
      routes: {
        '/node_modules': 'node_modules' //指定路由路径
      }
    }
  })
}

// 组合任务
const build = parallel(style, script, html, image)
const dev = series(clean, build, serve)

// 导出任务
module.exports = {
  build,
  dev,
  serve
}