美文网首页
gulp 笔记 要点概况

gulp 笔记 要点概况

作者: 秀秀_2d78 | 来源:发表于2019-11-12 16:00 被阅读0次
    gulp 是基于 node 实现 Web 前端自动化开发的工具。

    gulp 还可以做很多事,例如:

    • 压缩CSS
    • 压缩图片
    • 编译Sass/LESS
    • 编译CoffeeScript
    • markdown 转换为 html
    一、安装gulp

    1、安装gulp

    $ npm install -g gulp                            //安装全局包
    $ npm install -g gulp-cli                        //安装gulp-cli 
    

    2、创建项目目录并进入

    $ npx mkdirp my-project                           //使用mkdirp命令创建my-project目录
    $ cd my-project                                   //进入目录
    $ npm init  -y                                    //在项目目录下 创建 package.json 文件 
    

    3、安装 gulp,作为开发时依赖项

    $ npm install --save-dev gulp                    //安装到开发依赖
    $ gulp -v                                        //查看版本信息
    

    4、在项目根目录下创建一个名为 gulpfile.js 的文件:

    var gulp = require('gulp');
    gulp.task('default', function() {                 // 将你的默认的任务代码放在这
    });
    
    二、gulp基本转换流程

    1、找到 js/目录下的所有 .js 文件
    2、压缩这些 js 文件
    3、将压缩后的代码另存在 dist/js/ 目录下

    // 压缩 JavaScript 文件
    var gulp = require('gulp')                       // 获取 gulp
    var uglify = require('gulp-uglify')              // 获取 uglify 模块(用于压缩 JS)
    
    gulp.task('script', function(done) {
            gulp.src('js/*.js')                      // 1. src找到文件
            //.pipe是接受上一个流的结果,并返回一个处理后流的结果
            .pipe(uglify())                          // uglify 模块压缩文件
            .pipe(gulp.dest('dist/js'));             // dest输出压缩文件
            done();                                  //要求必须有回调函数
    });
    
    代码执行后文件结构
    └── js/
    │   └── a.js
    └── dist/
        └── js/
            └── a.js
    
    • src() 读取文件然后生成一个 Node 流(stream)。它将所有匹配的文件读取到内存中并通过流(stream)进行处理。
    • 流(stream)所提供的主要的 API 是 .pipe() 方法。
    • dest() 接受一个输出目录作为参数,它会将文件内容及文件属性写入到指定的目录中。

    gulp 还提供了 symlink() 方法,类似 dest(),但是创建的是链接而不是文件。

    三、特殊字符 * 、* *、!、{}
    gulp.src('./js/*.js')                           // * 匹配js文件夹下所有.js格式的文件
    gulp.src('./js/**/*.js')                        // ** 匹配js文件夹的0个或多个子文件夹
    gulp.src(['./js/*.js','!./js/index.js'])        // ! 匹配除了index.js之外的所有js文件
    gulp.src('./js/**/{omui,common}.js')            // {} 匹配{}里的文件名
    

    1、* ,对于匹配单级目录下的文件很有用。
    2、* * ,对于匹配嵌套目录下的文件很有用。
    3、! 反取,glob 数组中的取反必须跟在一个非取反的后面。

    四、任务(task)

    每个 gulp 任务(task)都是一个异步的 JavaScript 函数。
    此函数是一个可以接收 callback 作为参数的函数,或者是一个返回 stream、promise、event emitter、child process 或 observable 类型值的函数。

    1、导出任务
    被 gulpfile 导出(export)的任务为公开任务,未被导出的任务被认为是私有任务。

    const { series } = require('gulp');
    function clean(cb) {                             // clean函数未被export导出是私有任务
      // ...                                         // 它仍然可以被用在 series()组合中。
      cb();
    }
    function build(cb) {
      // ...                                         // 它仍然可以被用在 series()组合中。
      cb();                                
    }
    exports.build = build;     // build函数被export导出了是公开任务,可以被 gulp命令直接调用。
    exports.default = series(clean, build);
    
    • 公开任务(Public tasks) 从 gulpfile 中被导出(export),可以通过 gulp 命令直接调用。
    • 私有任务(Private tasks) 被设计为在内部使用,通常作为 series() 或 parallel() 组合的组成部分。

    2、组合任务
    Gulp 提供了两个强大的组合方法: series() 和 parallel(),允许将多个独立的任务组合为一个更大的操作。

    • 这两个方法都可以接受任意数目的任务(task)函数或已经组合的操作。
    • series() 和 parallel() 可以互相嵌套至任意深度。
    const { series } = require('gulp');
    function transpile(cb) {
      // ...   
      cb();
    }
    function bundle(cb) {
      // ...   
      cb();
    }
    exports.build = series(transpile, bundle);         //按顺序执行
    
    const { parallel } = require('gulp');
    function javascript(cb) {
      // ...  
      cb();
    }
    function css(cb) {
      // ...  
      cb();
    }
    exports.build = parallel(javascript, css);          //以最大并发来运行
    
    • 如果需要让任务(task)按顺序执行,请使用 series() 方法。
    • 对于希望以最大并发来运行的任务(tasks),可以使用 parallel() 方法。
    const { series, parallel } = require('gulp');
    function clean(cb) {
      // ...  
      cb();
    }
    function css(cb) {
      // ...  
      cb();
    }
    function javascript(cb) {
      // ...  
      cb();
    }
    exports.build = series(clean, parallel(css, javascript)); //可以任意嵌套
    
    五、异步执行

    当从任务(task)中返回 stream、promise、event emitter、child process 或 observable 时,成功或错误值将通知 gulp 是否继续执行或结束。如果任务(task)出错,gulp 将立即结束执行并显示该错误。

    1、返回 stream(流)

    const { src, dest } = require('gulp');
    function streamTask() {
      return src('*.js')
        .pipe(dest('output'));
    }
    exports.default = streamTask
    

    2、返回 promise(应答)

    function promiseTask() {
      return Promise.resolve('the value is ignored');
    }
    exports.default = promiseTask;
    

    3、返回 event emitter(事件发射器)

    const { EventEmitter } = require('events');
    function eventEmitterTask() {
      const emitter = new EventEmitter();
      // 发射必须异步,否则gulp无法监听
      setTimeout(() => emitter.emit('finish'), 250);
      return emitter;
    }
    exports.default = eventEmitterTask;
    

    4、返回 child process(子进程)

    const { exec } = require('child_process');
    function childProcessTask() {
      return exec('date');
    }
    exports.default = childProcessTask;
    

    5、返回 RxJS observable(观察对象)

    var Observable = require('rx').Observable;
    gulp.task('sometask', function() {
        return Observable.return(42);
    });
    

    6、使用 callback
    如果任务(task)不返回任何内容,则必须使用 callback 来指示任务已完成。示例中,callback 将作为cb() 的参数传递给你的任务(task)。

    function callbackTask(cb) {
      //...
      cb();
    }
    exports.default = callbackTask;
    

    如需通过 callback 把任务(task)中的错误告知 gulp,将 Error 作为 callback 的参数。

    function callbackError(cb) {
    //...
      cb(new Error('kaboom'));
    }
    exports.default = callbackError;
    

    7、使用 async/await
    如果不使用前面提供到几种方式,你还可以将任务(task)定义为一个 async 函数,它将利用 promise 对你的任务(task)进行包装。这将允许你使用 await 处理 promise,并使用其他同步代码。

    const fs = require('fs');
    async function asyncAwaitTask() {
      const { version } = fs.readFileSync('package.json');
      console.log(version);
      await Promise.resolve('some result');
    }
    exports.default = asyncAwaitTask;
    
    六、处理文件

    gulp 暴露了 src() 和 dest() 方法用于处理计算机上存放的文件。

    • 由 src() 产生的流(stream)应当从任务(task)中返回并发出异步完成的信号
    const { src, dest } = require('gulp');
    exports.default = function() {
      return src('src/*.js')
        .pipe(dest('output/'));
    }
    
    • 流(stream)所提供的主要的 API 是 .pipe() 方法,用于连接转换流(Transform streams)或可写流(Writable streams)。
    const { src, dest } = require('gulp');
    const babel = require('gulp-babel');
    exports.default = function() {
      return src('src/*.js')
        .pipe(babel())
        .pipe(dest('output/'));
    }
    
    • dest() 接受一个输出目录作为参数,当它接收到通过管道(pipeline)传输的文件时,它会将文件内容及文件属性写入到指定的目录中。
    • gulp 还提供了 symlink() 方法,其操作方式类似 dest(),但是创建的是链接而不是文件
    • 利用 .pipe() 方法将插件放置在 src() 和 dest() 之间,并转换流(stream)中的文件。
    • src() 也可以放在管道(pipeline)的中间,以根据给定的 glob 向流(stream)中添加文件。
    • 新加入的文件只对后续的转换可用。如果与之前的有重复,仍然会再次添加文件。
    const { src, dest } = require('gulp');
    const babel = require('gulp-babel');
    const uglify = require('gulp-uglify');
    exports.default = function() {
      return src('src/*.js')
        .pipe(babel())
        .pipe(src('vendor/*.js'))
        .pipe(uglify())
        .pipe(dest('output/'));
    }
    
    • dest() 可以用在管道(pipeline)中间用于将文件的中间状态写入文件系统。
    • 此功能可用于在同一个管道(pipeline)中创建未压缩(unminified)和已压缩(minified)的文件。
    const { src, dest } = require('gulp');
    const babel = require('gulp-babel');
    const uglify = require('gulp-uglify');
    const rename = require('gulp-rename');
    exports.default = function() {
      return src('src/*.js')
        .pipe(babel())
        .pipe(src('vendor/*.js'))
        .pipe(dest('output/'))
        .pipe(uglify())
        .pipe(rename({ extname: '.min.js' }))
        .pipe(dest('output/'));
    }
    

    流动(streaming)、缓冲(buffered)和空(empty)模式。这些模式可以通过对 src()bufferread 参数进行设置。、

    • 缓冲(Buffering)模式是默认模式,将文件内容加载内存中。插件通常运行在缓冲(buffering)模式下。
    • 流动(Streaming)模式主要用于操作无法放入内存中的大文件,例如巨幅图像或电影。文件内容从文件系统中以小块的方式流式传输,而不是一次性全部加载。
    • 空(Empty)模式不包含任何内容,仅在处理文件元数据时有用。
    七、文件监控

    gulp api 中的 watch() 方法利用文件系统的监控程序(file system watcher)将 globs 与 任务(task) 进行关联。它对匹配 glob 的文件进行监控,如果有文件被修改了就执行关联的任务(task)。

    const { watch, series } = require('gulp');
    function clean(cb) {
    //...
      cb();
    }
    function javascript(cb) {
    //...
      cb();
    }
    function css(cb) {
    //...
      cb();
    }
    watch('src/*.css', css);                          // 可以只关联一个任务
    watch('src/*.js', series(clean, javascript));     // 或者关联一个任务组合
    

    1、可监控的事件

    • 只要创建、更改或删除文件,文件监控程序就会执行关联的任务(task)
    • 可以在调用 watch() 方法时通过 events 参数进行指定。
    • 可用的有 'add'、'addDir'、'change'、'unlink'、'unlinkDir'、'ready'、'error'。
    • 还有一个 'all' 事件,它表示除 'ready' 和 'error' 之外的所有事件。
    const { watch } = require('gulp');
    // 所有事件都将被监控
    watch('src/*.js', { events: 'all' }, function(cb) {  
     //...
      cb();
    });
    

    2、初次执行
    调用 watch() 之后,任务只有在修改后还会执行。如需在文件修改之前执行,也就是调用 watch() 之后立即执行,请将 ignoreInitial 参数设置为 false

    const { watch } = require('gulp');
    // 关联的任务(task)将在启动时执行
    watch('src/*.js', { ignoreInitial: false }, function(cb) {
    //...
      cb();
    });
    

    3、队列
    每一次文件修改只产生一次关联任务的执行并放入队列中。如需禁止队列,请将 queue 参数设置为 false。

    const { watch } = require('gulp');
    //文件修改后任务都将执行有,可能并发执行
    watch('src/*.js', { queue: false }, function(cb) {   
    //...
      cb();
    });
    

    4、延迟
    文件更改之后,有 200 毫秒的延迟,文件监控程序所关联的任务(task)才会被执行。这是为了避免在同时更改多文件时(例如查找和替换操作)过早启动任务(taks)的执行。
    如需调整延迟时间,请为 delay 参数设置一个正整数。

    const { watch } = require('gulp');
    // 文件修改后等待 500 毫秒执行任务
    watch('src/*.js', { delay: 500 }, function(cb) {   
    //...
      cb();
    });
    

    相关文章

      网友评论

          本文标题:gulp 笔记 要点概况

          本文链接:https://www.haomeiwen.com/subject/caifictx.html