Site Overlay

前端工程化-Gulp

目的

了解工程化的好处以及gulp的运用

gulp特点:
1. 任务化
2. 基于流
3. 同步/异步

步骤

1. 环境搭建

# 1.全局安装Gulp,代表你的电脑拥有了命令行执行gulp任务的能力
npm i -g gulp-cli

# 2.创建项目目录
mkdir my-project

# 3.进入项目
cd my-project

# 4.快速初始化npm
npm init -y

# 5.在项目中安装gulp作为开发依赖
npm i gulp -D

# 6.安装压缩css,js,html的插件,也作为开发依赖
npm i gulp-htmlmin gulp-clean-css gulp-uglify -D

gulp命令行
gulp my_task(任务名) ? 执行my_task任务
gulp ? 默认执行default任务

2. 创建配置文件

在项目根目录创建.gulpfile的配置文件(在运行 gulp 命令时该文件会被自动加载)
gulp的API
1. task() ? 注册gulp任务
2. src() ? 接收glob(普通字符或通配字符组成的字符串,匹配文件路径)参数,生成node流
3. dest() ? 接收输出目录,生成node流(终止流)

// 注册压缩html任务
const htmlmin = require('gulp-htmlmin');

gulp.task('htmlMin', () => {
  return gulp.src('src/*.html') // 匹配src下的html文件,不包括src/xx/xx.html
    .pipe(htmlmin({
      // 常用配置
      collapseWhitespace: true, // 去除文档树中文本节点的空白
      minifyCSS: true, // 压缩页面中的css
      minifyJS: true, // 压缩页面中的js
      removeEmptyAttributes: true, // 去除element中属性为空的
      removeComments: true, // 去除注释
      collapseBooleanAttributes: true, // 为真的简写 如: <input value="foo" readonly="readonly"> 变为 <input value="foo" readonly>
    }))
    .pipe(gulp.dest('dist')) // 输出到dist目录
});
// 注册转换less为css后,压缩合并css任务
const concat = require('gulp-concat');
const less = require('gulp-less');
const cleanCss = require('gulp-clean-css');

// 处理less
gulp.task('less', function() {
  return gulp.src('src/css/*.less')
    .pipe(less()) // 将less转化为css
    .pipe(gulp.dest('./src/css')) // 输出到css文件下,为了和css文件一起压缩合并为一个文件
});

// 压缩合并css
// 压缩css前先执行less转换任务
gulp.task('cssMin', function() {
  return gulp.src('src/css/*.css')
    .pipe(concat('build.css')) // 合并后命名为build.css文件
    .pipe(cleanCss({compatibility: 'ie8'}))
    .pipe(gulp.dest('dist/css'))
});

? 思考:如何保证less全转化完后再执行css合并压缩任务?

// task()还可以传另一个参数
gulp.task('cssMin', ['less'], function() {
  return gulp.src('src/css/*.css')
    .pipe(concat('build.css'))
    .pipe(cleanCss({compatibility: 'ie8'})) // 兼容模式ie8+
    .pipe(gulp.dest('dist/css'))
});

这样在执行gulp cssMin时就能保证先将less转化为css后再执行cssMin任务

关于css其他好用的插件
gulp-rename ? 重命名文件
gulp-autoprefixer ? 自动添加css浏览器前缀

// 注册压缩js任务
const uglify = require('gulp-uglify');

gulp.task('jsMin', function() {
  return gulp.src('src/js/*.js')
    .pipe(concat('build.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist/js'))
});

? 一个个手动输入gulp + 任务名 很麻烦,思考:如何一次性执行三个任务?
? 注册默认default 任务

// 直接执行gulp就会执行三个任务
gulp.task('default', ['htmlMin', 'cssMin', 'jsMin']);

(注意:以上代码只能在gulp3的环境中有效运行)

3. 对比Gulp4

gulp.task移除了三参数语法,不能使用数组来指定一个任务的依赖。gulp 4.0 加入了 gulp.seriesgulp.parallel 来实现任务的串行化和并行化。

gulp.task('cssMin', function() { // 去掉['less']
  return gulp.src('src/css/*.css')
    .pipe(concat('build.css'))
    .pipe(cleanCss({compatibility: 'ie8'}))
    .pipe(gulp.dest('dist/css'))
});

// 运用series和parallel,先执行less,再执行剩下的三个(并行运行)
gulp.task('default', gulp.series('less', gulp.parallel('htmlMin', 'cssMin', 'jsMin')));

4.半自动构建

const livereload = require('gulp-livereload');

 gulp.task('watch', function() {
  // 开启监听
  livereload.listen();

  // 确认监听的目标以及绑定相应的任务
  gulp.watch('src/*.html', ['htmlMin']);
  gulp.watch('src/js/*.js', ['jsMin']);
  gulp.watch(['src/less/*.less', 'src/css/*.css'], ['cssMin']);
})

当src里面的文件有修改时,直接手动刷新浏览器,则可以看到变化,不需要每改一次就手动重新构建项目

所有需要实时监听的任务,后面加上:.pipe(livereload())

?‍♂️ 虽然不用手动构建了,但还需要刷新,如何做到不刷新页面,页面就自动更改? ? 热更新

5. 全自动构建项目

const connect = require('gulp-connect');

// 注册
gulp.task('connect', function() {
  // 配置服务器选项
  connect.server({
    root: 'dist',
    livereload: true, //实时刷新
    port: 3000, // 定端口
  });

  gulp.watch('src/*.html', ['htmlMin']);
  gulp.watch('src/js/*.js', ['jsMin']);
  gulp.watch(['src/less/*.less', 'src/css/*.css'], ['cssMin']);
});

所有需要实时监听的任务,后面加上:.pipe(connect.reload())

完整代码

const gulp = require('gulp');
const htmlmin = require('gulp-htmlmin');
const cleanCss = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');
const less = require('gulp-less');
const connect = require('gulp-connect');

// 压缩html
gulp.task('htmlMin', () => {
  // 代码
  ...
  .pipe(connect.reload())
});

// 处理less
gulp.task('less', function() {
  // 代码
  ...
  .pipe(connect.reload())
});

// 压缩合并css
// 压缩css前先执行less转换任务
gulp.task('cssMin', function() {
  // 代码
  ...
  .pipe(connect.reload())
});

// 压缩合并js
gulp.task('jsMin', function() {
  // 代码
  ...
  .pipe(connect.reload())
});

gulp.task('connect', function() {
  connect.server({
    root: 'dist',
    livereload: true,
    port: 3000,
  });

  gulp.watch('src/*.html', ['htmlMin'])
  gulp.watch('src/js/*.js', ['jsMin'])
  gulp.watch(['src/less/*.less', 'src/css/*.css'], ['cssMin'])
});

gulp.task('default', gulp.series('less', gulp.parallel('cssMin', 'jsMin', 'htmlMin', 'connect')));