前端 Gulp 详细介绍与案例使用

简介: 前端 Gulp 详细介绍与案例使用

一、简介

  • 前端常见打包构建工具:gulpwebpack
  • gulp 是基于 的打包构建工具。webpack 是基于 js 文件的打包构建工具。
  • 什么是
  • 流文件:一种文件传输的格式,一段一段的文件传输,全部下载完成后再转换成指定文件格式,例如视频、音频、压缩包下载。
  • 流格式:从头到尾的一个过程,从 开始一步一步,每一个步骤都需要依赖上一步的结果,最终给出一个完成的成品。
  • gulp 是基于 格式的一种打包构建工具。
  • 依赖环境
  • 依赖与 node 环境进行开发
  • 底层封装的内容主要用到了 node 里面的文件读写(httpfs
  • 作用
  • 对于 css 文件可以进行 压缩,转码(自动添加前缀)(例如:scss -》css -》添加前缀 -》压缩 ....) 。
  • 对于 js 文件可以进行 压缩,转码(ES6 转 ES5)
  • 对于 html 文件可以进行 压缩,转码(对格式的转换)
  • 对于 静态资源文件 的处理,对于 第三方文件 的处理 …

二、安装

  • gulp 使用的主流版本分为 gulp@3.xgulp@4.x,本篇使用 4.x 版本。
  • 安装
# 安装全局 gulp,基础库,如果不安装全局会报错 # zsh: command not found: gulp
$ npm i gulp -g
# 如果 mac 有权限限制的话,用这个
$ sudo npm i gulp -g
# 安装项目 gulp,基础库
$ npm i gulp -D
  • 后续 gulp 的插件(用于压缩 cssjs 等任务要用到的)都安装到 devDependencies
  • 检查是否安装成功(4.x 输出的是 cli 版本号,3.x 输出的是 gulp 3.9.0 版本号)
$ gulp -v
CLI version: 2.3.0
Local version: Unknown
  • 运行指令(下面案例中体现使用场景)
$ gulp xxx
  • 创建一个 gulpfile.js 文件,这个是 gulp 配置文件,后续的执行任务都写在这个配置文件中,gulp 会执行一遍配置中的任务。

三、常用 API

gulp 的常用 API
  + 前提: 下载 gulp 第三方, 导入以后使用
1. gulp.task()
  => 语法: gulp.task(任务名称, 任务处理函数)
  => 作用: 创建一个基于流的任务
  => 例子: gulp.task('htmlHandler', function () {
    // 找到 html 源文件, 进行压缩, 打包, 放入指定目录
  })
2. gulp.src()
  => 语法: gulp.src(路径信息)
  => 作用: 找到源文件
  => 书写方式
    2-1. gulp.src('./a/b.html')
      -> 找到指定一个文件
    2-2. gulp.src('./a/*.html')
      -> 找到指定目录下, 指定后缀的文件
    2-3. gulp.src('./a/**')
      -> 找到指令目录下的所有文件
    2-4. gulp.src('./a/** /*')
      -> 找到 a 目录下所有子目录里面的所有文件
    2-5. gulp.src('./a/** /*.html')
      -> 找到 a 目录下所有子目录里面的所有 .html 文件
3. gulp.dest()
  => 语法: gulp.dest(路径信息)
  => 作用: 把一个内容放入指定目录内
  => 例子: gulp.dest('./abc')
    -> 把他接收到的内容放到 abc 目录下
4. gulp.watch()
  => 语法: gulp.watch(路径信息, 任务名称)
  => 作用: 监控指定目录下的文件, 一旦发生变化, 从新执行后面的任务
  => 例子: gulp.watch('./src/pages/*.html', htmlHandler)
    -> 当指定目录下的 html 文件发生变化, 就会执行 htmlHandler 这个任务
5. gulp.series()
  => 语法: gulp.series(任务1, 任务2, 任务3, ...)
  => 作用: 逐个执行多个任务, 前一个任务结束, 第二个任务开始
6. gulp.parallel()
  => 语法: gulp.parallel(任务1, 任务2, 任务3, ...)
  => 作用: 并行开始多个任务
7. pipe()
  => 管道函数
  => 所有的 gulp API 都是基于流
  => 接收当前流, 进入下一个流过程的管道函数
  => 例子:
    gulp.src().pipe(压缩任务).pipe(转码).pipe(gulp.dest('abc'))

三、常用插件

gulp 常用插件
  + gulp 的各种插件就是用来执行各种各样的压缩混淆转码任务的
1. gulp-cssmin
  => 下载: npm i gulp-cssmin -D
  => 导入: const cssmin = require('gulp-cssmin')
  => 导入以后得到一个处理流文件的函数
  => 直接再管道函数里面执行就好了
2. gulp-autoprefixer
  => 下载: npm i gulp-autoprefixer -D
  => 导入: const autoPrefixer = require('gulp-autoprefixer')
  => 导入以后得到一个处理流文件的函数
  => 直接再管道函数里面使用, 需要传递参数
    -> { browsers: [要兼容的浏览器] }
3. gulp-sass
  => 下载: npm i gulp-sass -D
    -> 很容易报错, 基本下载不成功
    -> 为什么: 因为 gulp-sass 依赖另一个第三方, node-sass
      => node-sass 很难下载成功
      => 以前都是再一个地方下载, 后来 node-sass 自己单独有一个下载地址
      => 如果不进行单独的 node-sass 下载地址配置, 就很容易失败
    -> 解决: 给 node-sass 单独配置一个下载地址
      => 下载 node-sass 从这个单独的地址下载, 下载其他的东西还是统一地址
    -> node-sass 单独下载地址
      => $ set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/
      => 单独配置一个下载地址, 只有下载 node-sass 的时候会使用
    -> 过程
      1. $ set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/
      2. $ npm i node-sass -D
      3. $ npm i gulp-sass -D
  => 导入: const sass = require('gulp-sass')
  => 导入以后得到一个可以处理流文件的函数, 直接再管道函数里面执行就可以了
4. gulp-uglify
  => 把 JS 文件压缩的
  => 下载: npm i -D gulp-uglify
  => 导入: const uglify = require('gulp-uglify')
  => 导入以后得到一个可以处理流文件的函数
  => 直接再管道函数中使用就可以了
  => 注意: 你不能写 ES6 语法, 一旦有了 ES6 语法就会报错
5. gulp-babel
  => 专门进行 ES6 转 ES5 的插件
  => gulp-babel 的版本
    -> gulp-babel@7: 大部分使用再 gulp@3 里面
    -> gulp-babel@8: 大部分使用再 gulp@4 里面
  => 下载:
    -> gulp-babel 需要依赖另外两个包, 要一起下载
    -> 另外两个包: @babel/core  @babel/preset-env
  => 导入:
    -> 只要导入一个包就够了, 他会自动导入另外两个包
    -> const babel = require('gulp-babel')
  => 导入以后得到一个可以处理流文件的函数
  => 直接再管道函数内部使用, 需要传递参数
6. gulp-htmlmin
  => 下载: npm i -D gulp-htmlmin
  => 导入: const htmlmin = require('gulp-htmlmin')
  => 导入以后得到一个可以处理流文件的函数
  => 直接再管道函数里面调用, 需要传递参数
7. del
  => 下载: npm i -D del
  => 作用: 删除文件目录
  => 导入: const del = require('del')
  => 导入以后得到一个函数, 直接使用传递参数就可以了
8. gulp-webserver
  => 作用: 启动一个基于 node 书写的服务器
  => 下载: npm i -D gulp-webserver
  => 导入: const webserver = require('gulp-webserver')
  => 导入以后得到一个处理流文件的函数
  => 在管道函数内调用就可以了, 需要传递参数
9. gulp-file-include
  => 作用: 再一个 html 页面里面导入一个 html 片段
  => 下载: npm i -D gulp-file-include
  => 导入: const fileInclude = require('gulp-file-include')
  => 导入以后得到一个处理流文件的函数
  => 在管道函数内调用就可以了, 需要传递参数

三、案例需求

  • 打包自己的项目1、要确定好自己的目录结构2、要分开源码和打包后的内容例如:打包pages/index.html代码,打包完毕放在哪?同级目录下,再次创建叫做pages的文件夹?不行,因为不能创建同名文件夹。同级目录下,创建叫做views的文件夹?不行,因为页面中的资源路径会找不到,路径变了。必须要保证打爆前后的目录接口一致,这样才不会导致资源文件路径找不到等问题:
  • 创建一个叫做 src 的目录(表示源码)
  • 创建一个叫做 dist 的目录(存放打包后的文件)
  • 案例项目结构
- my_project    项目
  - dist        打包文件(没有会自行创建,每次打包会删除在重新创建)
  - src         源码
    + pages     html
    + css       css
    + js        js
    + sass      sass(需要将 sass 转成 css 进行使用)
    + images    图片
    + videos    视频
    + audios    音频
    + lib       第三方文件
    + fonts     字体图标文件
  • 案例项目 gulpfile.js 配置
// gulp 配置文件
// 0. 导入第三方
// 0-1. 导入 gulp
const gulp = require('gulp')
// 0-2. 导入 gulp-cssmin
const cssmin = require('gulp-cssmin')
// 0-3. 导入 gulp-autoprefixer
const autoPrefixer = require('gulp-autoprefixer')
// 0-4. 导入 gulp-sass
const sass = require('gulp-sass')
// 0-5. 导入 gulp-uglify
const uglify = require('gulp-uglify')
// 0-6. 导入 gulp-babel
const babel = require('gulp-babel')
// 0-7. 导入 gulp-htmlmin
const htmlmin = require('gulp-htmlmin')
// 0-8. 导入 del
const del = require('del')
// 0-9. 导入 gulp-webserver
const webserver = require('gulp-webserver')
// 0-10. 导入 gulp-file-include
const fileInclude = require('gulp-file-include')
// 1. 创建任务
// 1-1. 创建一个打包 css 的任务
const cssHandler = function () {
  return gulp
    .src('./src/css/*.css')   // 1. 找到内容
    .pipe(autoPrefixer())     // 2. 自动添加前缀
    .pipe(cssmin())           // 3. 压缩
    .pipe(gulp.dest('./dist/css/')) // 4. 放到指定目录
}
// 1-2. 创建一个打包 sass 文件的任务
const sassHandler = function () {
  return gulp
    .src('./src/sass/*.scss')
    .pipe(sass())
    .pipe(autoPrefixer())
    .pipe(cssmin())
    .pipe(gulp.dest('./dist/sass/'))
}
// 1-3. 创建一个打包 js 文件的任务
const jsHandler = function () {
  return gulp
    .src('./src/js/*.js')    // 1. 找到 js 文件
    .pipe(babel({
      // babel@7, presets: ['es2015']
      presets: ['@babel/env']
    }))
    .pipe(uglify())
    .pipe(gulp.dest('./dist/js/'))
}
// 1-4. 创建一个打包 html 文件的任务
const htmlHandler = function () {
  return gulp
    .src('./src/pages/*.html')
    // .pipe(fileInclude({ // 根据你的配置导入对应的 html 片段,也就是组件
    //   prefix: '@-@', // 你自定义的一个标识符
    //   basepath: './src/components' // 基准目录, 你的组件文件都在哪一个目录里面
    // }))
    .pipe(htmlmin({ // 通过你配置的参数来进行压缩
      // collapseWhitespace: true, // 表示移出空格
      removeEmptyAttributes: true, // 表示移出空的属性(仅限于原生属性)
      collapseBooleanAttributes: true, // 移出 checked 类似的布尔值属性
      removeAttributeQuotes: true, // 移出属性上的双引号
      minifyCSS: true, // 压缩内嵌式 css 代码(只能基本压缩, 不能自动添加前缀)
      minifyJS: true, // 压缩内嵌式 JS 代码(只能基本压缩, 不能进行转码)
      removeStyleLinkTypeAttributes: true, // 移出 style 和 link 标签上的 type 属性
      removeScriptTypeAttributes: true, // 移出 script 标签上默认的 type 属性
    }))
    .pipe(gulp.dest('./dist/pages/'))
}
// 1-5. 创建一个打包 images 文件的任务
const imgHandler = function () {
  return gulp
    .src('./src/images/**')
    .pipe(gulp.dest('./dist/images/'))
}
// 1-6. 创建一个打包 videos 文件的任务
const videoHandler = function () {
  return gulp
    .src('./src/videos/**')
    .pipe(gulp.dest('./dist/videos/'))
}
// 1-7. 创建一个打包 audios 文件的任务
const audioHandler = function () {
  return gulp
    .src('./src/audios/**')
    .pipe(gulp.dest('./dist/audios/'))
}
// 1-8. 创建一个打包 第三方 的任务
const libHandler = function () {
  return gulp
    .src('./src/lib/**/*')
    .pipe(gulp.dest('./dist/lib/'))
}
// 1-9. 创建一个打包 fonts 文件的任务
const fontHandler = function () {
  return gulp
    .src('./src/fonts/**/*')
    .pipe(gulp.dest('./dist/fonts/'))
}
// 1-10. 创建一个删除 dist 目录的任务
const delHandler = function () {
  // del 直接执行就可以了, 不需要流
  // 参数以数组的形式传递你要删除的文件夹
  return del(['./dist/'])
}
// 1-11. 创建一个启动 服务器 的任务
const webHandler = function () {
  return gulp
    .src('./dist')
    .pipe(webserver({
      host: 'www.gx.com', // 域名(可以配置自定义域名)
      port: '8080', // 端口号
      livereload: true, // 当文件修改的时候, 是否自动刷新页面
      open: './pages/login.html', // 默认打开哪一个文件(从 dist 目录以后的目录开始书写)
      proxies: [ // 配置你的所有代理
        // 每一个代理就是一个对象数据类型
        // 注意: 如果你没有代理, 不要写空对象
        {
          // 代理标识符
          source: '/dzm1',
          // 代理目标地址
          target: 'https://www.dzm.com/api/'
        },
        {
          source: '/dzm2',
          target: 'https://www.xyq.com/api/'
        },
        {
          source: '/dzm3',
          target: 'https://www.xxx.com/api/'
        }
      ]
    }))
}
// 1-12. 创建一个监控任务
const watchHandler = function () {
  // 使用 gulp.watch()
  gulp.watch('./src/sass/*.scss', sassHandler)
  gulp.watch('./src/css/*.css', cssHandler)
  gulp.watch('./src/js/*.js', jsHandler)
  gulp.watch('./src/pages/*.html', htmlHandler)
}
// 2. 导出任务(这种单个导出需要单个执行)
// 2-1. 导出打包 css 的任务
// module.exports.cssHandler = cssHandler
// // 2-2. 导出打包 sass 的任务
// module.exports.sassHandler = sassHandler
// // 2-3. 导出打包 js 的任务
// module.exports.jsHandler = jsHandler
// // 2-4. 导出打包 html 的任务
// module.exports.htmlHandler = htmlHandler
// // 2-5. 导出打包 images 的任务
// module.exports.imgHandler = imgHandler
// // 2-6. 导出打包 videos 的任务
// module.exports.videoHandler = videoHandler
// // 2-7. 导出打包 audios 的任务
// module.exports.audioHandler = audioHandler
// // 2-8. 导出打包 第三方 的任务
// module.exports.libHandler = libHandler
// // 2-9. 导出打包 fonts 的任务
// module.exports.fontHandler = fontHandler
// // 2-10. 导出删除 dist 目录的任务
// module.exports.delHandler = delHandler
// 3. 配置一个默认任务
// 默认任务的作用就是把所有的任务一起执行了
// 要么使用 gulp.series(), 要么使用 gulp.parallel()
// 这两个方法的返回值是一个函数, 返回值可以直接被当作任务函数使用
// 使用 task 的方式创建一个 default 任务
// 方式1:
// gulp.task('default', () => {})
// 方式2:
// module.exports.default = () => {}
// 举例:创建一个默认任务(这种就可以一起执行,不需要单个导出执行)
// module.exports.default = gulp.parallel(cssHandler, sassHandler, jsHandler, htmlHandler, imgHandler, videoHandler, audioHandler, libHandler, fontHandler)
// 配置一个默认任务
// 这个是完整的流程:1、删除dist 2、创建压缩到dist 3、启用本地代理(也可以使用 nginx 代替)4、热更新监听文件变化进行编译
module.exports.default = gulp.series(
  delHandler,
  gulp.parallel(cssHandler, sassHandler, jsHandler, htmlHandler, imgHandler, videoHandler, audioHandler, libHandler, fontHandler),
  webHandler,
  watchHandler
)
  • 组件使用案例,不清楚可自行查查。

相关文章
|
2月前
|
搜索推荐 前端开发 数据可视化
【优秀python web毕设案例】基于协同过滤算法的酒店推荐系统,django框架+bootstrap前端+echarts可视化,有后台有爬虫
本文介绍了一个基于Django框架、协同过滤算法、ECharts数据可视化以及Bootstrap前端技术的酒店推荐系统,该系统通过用户行为分析和推荐算法优化,提供个性化的酒店推荐和直观的数据展示,以提升用户体验。
|
6天前
|
前端开发 JavaScript
前端一键回到顶部案例
本文介绍了如何实现网页中的一键回到顶部功能,包括两种方法:第一种是通过HTML中的锚点跳转实现快速回到顶部;第二种是使用JavaScript的`scrollTo`方法结合`requestAnimationFrame`实现滚动动画效果,让页面滚动更加平滑自然。
10 1
前端一键回到顶部案例
|
21天前
|
前端开发 数据安全/隐私保护
【前端web入门第二天】03 表单-下拉菜单 文本域 label标签 按钮 【附注册信息综合案例】
本文档详细介绍了HTML表单的多种元素及其用法,包括下拉菜单(`<select>` 和 `<option>`)、文本域(`<textarea>`)、标签解释(`<label>`)、各类按钮(`<button>`)及表单重置功能、无语义布局标签(`<div>` 和 `<span>`)以及字符实体的应用。此外,还提供了一个完整的注册信息表单案例,涵盖个人信息、教育经历和工作经历等部分,展示了如何综合运用上述元素构建实用的表单。
【前端web入门第二天】03 表单-下拉菜单 文本域 label标签 按钮 【附注册信息综合案例】
|
6天前
|
JavaScript 前端开发
前端基础(十)_Dom自定义属性(带案例)
本文介绍了DOM自定义属性的概念和使用方法,并通过案例展示了如何使用自定义属性来控制多个列表项点击变色的独立状态。
16 0
前端基础(十)_Dom自定义属性(带案例)
|
8天前
|
JSON 前端开发 JavaScript
socket.io即时通信前端配合Node案例
本文介绍了如何使用socket.io库在Node.js环境下实现一个简单的即时通信前端配合案例,包括了服务端和客户端的代码实现,以及如何通过socket.io进行事件的发送和监听来实现实时通信。
14 2
|
20天前
|
前端开发
【前端web入门第五天】03 清除默认样式与外边距问题【附综合案例产品卡片与新闻列表】
本文档详细介绍了CSS中清除默认样式的方法,包括清除内外边距、列表项目符号等;探讨了外边距的合并与塌陷问题及其解决策略;讲解了行内元素垂直边距的处理技巧;并介绍了圆角与盒子阴影效果的实现方法。最后通过产品卡片和新闻列表两个综合案例,展示了所学知识的实际应用。
29 11
|
20天前
|
前端开发
前端web入门第四天】03 显示模式+综合案例热词与banner效果
本文档介绍了HTML中标签的三种显示模式:块级元素、行内元素与行内块元素,并详细解释了各自的特性和应用场景。块级元素独占一行,宽度默认为父级100%,可设置宽高;行内元素在同一行显示,尺寸由内容决定,设置宽高无效;行内块元素在同一行显示,尺寸由内容决定,可设置宽高。此外,还提供了两个综合案例,包括热词展示和banner效果实现,帮助读者更好地理解和应用这些显示模式。
|
23天前
|
JavaScript 前端开发
【前端web入门第一天】03 综合案例 个人简介与vue简介
该网页采用“从上到下,先整体再局部”的制作思路,逐步分析并编写代码实现个人简介页面。内容涵盖尤雨溪的背景、学习经历及主要成就,同时介绍其开发的Vue.js框架特点。代码结构清晰,注重细节处理,如使用快捷键提高效率,预留超链接位置等,确保最终效果符合预期。
|
2月前
|
前端开发 大数据 数据库
🔥大数据洪流下的决战:JSF 表格组件如何做到毫秒级响应?揭秘背后的性能魔法!💪
【8月更文挑战第31天】在 Web 应用中,表格组件常用于展示和操作数据,但在大数据量下性能会成瓶颈。本文介绍在 JavaServer Faces(JSF)中优化表格组件的方法,包括数据处理、分页及懒加载等技术。通过后端分页或懒加载按需加载数据,减少不必要的数据加载和优化数据库查询,并利用缓存机制减少数据库访问次数,从而提高表格组件的响应速度和整体性能。掌握这些最佳实践对开发高性能 JSF 应用至关重要。
45 0
|
2月前
|
前端开发 JavaScript 开发者
fuse.js前端搜索简单使用的三个案例
通过这三个例子可以看出,Fuse.js 是一个功能丰富、易于实现的前端搜索库。它使开发者能够便捷地实现从基础到高级的搜索功能,无论是简单的列表搜索还是实时的搜索建议,都能够高效、精确地提供给用户所需的信息。
80 0