自动化构建工具-Gulp

362 阅读6分钟

这是我参与 8 月更文挑战的第 4 天,活动详情查看: 8月更文挑战

Gulp与npm scripts

Gulp与npm scripts 都能实现自动化构建

Gulp语法简单

  • Gulp语法就是JavaScript语法
  • npm scripts 语法接近shell脚本
    • (举例:minify output.css > output.min.css)

Gulp生态完善,构建效率高

Gulp基本使用

步骤

  • 全局安装Gulp客户端 npm install -g gulp-cli

  • 初始化项目 npm init --yes

    • 出现package.json文件
  • 安装Gulp包 npm install gulp -D

  • 新建gulpfile文件 gulpfile.js

  • 在gulpfile.js中,创建gulp任务

    • 演示代码(gulpfile.js)
          // 新建Gulp任务
        const task1 = () => {
            console.log("task1 is running");
        }
        const task2 = () => {
            console.log("task2 is running");
        }
      
        // 将任务暴露
        module.exports = {
            task1,
            task2
        }
      
  • 执行gulp任务 gulp <task-name>

    • 演示

        // 执行任务
        gulp task1
        // 控制台执行成功后报错
        //The following tasks did not complete: task1
        //Did you forget to signal async completion?
        // 是不是忘记发送一个异步完成的信号?
      
    • 报错的解决方法:给任务传递一个回调函数

        // 修改后的代码
        const task1 = (cd) => {
        console.log("task1 is running");
        cd();
        }
        //[14:38:31] Starting 'task1'...
        //task1 is running
        //[14:38:31] Finished 'task1' after 2.44 ms
      

default 默认任务

  • 当有任务是以default暴露出来命名时,执行的时候可以只输入gulp,省略任务名
  • 演示代码
// 新建Gulp任务
const task1 = (cd) => {
    console.log("task1 is running");
    cd();
}
const task2 = (cd) => {
    console.log("task2 is running");
    cd();
}

// 将任务暴露
module.exports = {
    task1,
    default:task2
}

// 执行命令 Gulp
// 输出结果
// Starting 'default'...
// task2 is running
// Finished 'default' after 2.69 ms

旧版Gulp任务的声明方式

  • 演示代码
// 引入Gulp包
const gulp = require('gulp');

// 创建Gulp任务
gulp.task('task3',(cd) => {
    console.log('task3 is running');
    cd();
});
// 不用将任务导出

// 执行命令
gulp taske3
  • 总结
    • 旧版 不用导出任务,但是要引入gulp包

Gulp组合任务

  • 新版本中所有的任务都是异步执行
  • 异步执行的有:ES6中的promise \ 流 \ 回调函数

gulp任务和npm scripts命令

  • gulp任务和npm scripts命令的执行方式一样

Gulp组合任务详解

  • 并行:gulp.parallel(task1,task2,task3)
  • 串行:gulp.series(task1,task2,task3)
  • gulp任务公共代码结构
// 引入gulp包
const gulp = require('gulp');

// 创建任务
const task1 = (cd) => {
    setTimeout(() => {
        console.log('task1 is running');
    },1000);
    cd();
}
const task2 = (cd) => {
    setTimeout(() => {
        console.log('task2 is running');
    },1000);
    cd();
}
const task3 = (cd) => {
    setTimeout(() => {
        console.log('task3 is running');
    },1000);
    cd();
}

串行

  • 代码演示
// 串行
exports.s = gulp.series(task1,task2,task3);
  • 执行结果

gulp串行.png

并行(可以提高效率)

  • 代码演示
// 导出任务
// 并行
exports.p = gulp.parallel(task1,task2,task3);
  • 执行结果

gulp并行.png

Gulp构建组合任务

gulp构建组合任务.png

  • gulp.series(task1,gulp.parallel(task2,task3),task4);

Gulp文件操作

回顾文件操作

  • 缓冲方式:源文件 -> 内存缓冲 -> 目标文件
    • 缺点:需要缓冲区域足够大,如果一次放不下源文件,则会产生文件操作失败。
  • 流方式
    • 将一个大的文件切成小块,每个小块都有一个编码,最后在目的地通过编号的顺序,将其再拼接起来。
    • 通过管道进行传输,异步执行。
  • Gulp的文件操作是基于流的。

Gulp文件操作的特点

  • 1.任务化,所有的构建都是任务。
  • 2.基于流,文件操作都是基于流的。

Gulp是基于流的构建系统

  • 输入:读取流
  • 加工:转换流
  • 输出:写入流

Gulp管道流

  • 具体的Gulp文件操作图

Gulp文件操作.png

  • Gulp管道流

Gulp管道流.png

案例

  • 补充
    • dest : destination 目的地
  • 基础案例:将src文件夹下面的main.css文件移动到dest文件夹下
// 创建任务
const task = (cd) => {
    // 获取当前的路径,之后通过管道进行传输到目的地
    gulp.src('src/main.css').pipe(gulp.dest('dest'));
    cd();
}
  • 进阶案例(保证传输过来的文件结构也一致):将src文件夹中styles文件夹下面的main.css文件移动到dest文件夹中styles文件夹下
  • 演示代码1
// 创建任务
const task = (cd) => {
    // 获取当前的路径,之后通过管道进行传输到目的地
    gulp.src('src/styles/main.css',{base:'src'}).pipe(gulp.dest('dest'));
    cd();
}
  • 演示代码2 使用ES6中的解构方法,优点:不用每次都写gulp点函数调用,可以直接用函数名
// // 引入gulp包
const {src,dest} = require('gulp');

// 创建任务
const task = (cd) => {
    // 获取当前的路径,之后通过管道进行传输到目的地
    src('src/styles/main.css',{base:'src'}).pipe(dest('dest'));
    cd();
}

Gulp构建样式文件

  • Gulp中有很多有用的插件,可以在Gulp的官网中(gulpjs.com)查找到。
  • 可以在Gulp的官网上查看到,很多插件其实是引用npmjs.com的地址的,因此也可以直接去npmjs.com上去查找

Gulp和npm scripts插件

  • 名称不完全相同
  • Gulp使用起来更简单

Gulp构建样式文件步骤

Gulp 将less转换css

  • 1.引入插件(npmjs.com中搜索,看使用教程)
  • 2.导入包
  • 3.写在pipe中
  • 注意:因为流原本就是异步的,因此就不需要再写回调函数了。
  • 演示代码:成功将main.less文件转换为main.css,并存储在目的文件夹下面
// // 引入gulp包
const {src,dest} = require('gulp');
const less = require('gulp-less');

// 创建任务
const task = (cd) => {
    // 获取当前的路径,之后通过管道进行传输到目的地
    // src('src/styles/main.css',{base:'src'}).pipe(dest('dest'));
    return src('src/styles/main.less')
    .pipe(less())
    .pipe(dest('src/styles'));
}
// 输出:成功将main.less文件转换为main.css,并存储在目的文件夹下面

Gulp 转换、压缩、重命名 构建样式文件

  • npm i gulp-less -D 将less文件,转成css文件
  • npm i gulp-clean-css -D 压缩css文件
  • npm i gulp-rename -D 对文件进行重命名
  • 演示代码
// // 引入gulp包
const {src,dest} = require('gulp');
// 转换
const less = require('gulp-less');
// 压缩
const clean = require('gulp-clean-css');
// 重命名
const rename = require('gulp-rename');

// 创建任务
const task = (cd) => {
    // 获取当前的路径,之后通过管道进行传输到目的地
    // src('src/styles/main.css',{base:'src'}).pipe(dest('dest'));
    return src('src/styles/main.less')
    .pipe(less())
    .pipe(clean())
    .pipe(rename({extname:".min.css"}
    ))
    .pipe(dest('dest'));
}
  • 注意:流原本就是异步的,因此不需要再写回调函数

CSS hack与Autoprefixer

  • 保证css兼容性

CSS hack

  • css代码存在兼容性问题
    • 同一段css代码,在不同浏览器上的呈现效果不同。

补充

  • Gulp中的任何一个构建内容,都称之为任务(像之前的文件的压缩、转换),本质上,任务就是一个js函数
  • 新版的Gulp中做了一个约定,所有的Gulp任务都是异步的.

附录

回调函数

  • 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。回答完毕