Gulp学习笔记

作者: 淡就加点盐 | 来源:发表于2017-03-30 19:58 被阅读137次

    P1 简介

    gulp是基于Nodejs的自动任务运行器, 它能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并监听文件在改动后重复指定的这些步骤。在实现上,她借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入,使得在操作上非常简单。通过本文,我们将学习如何使用Gulp来改变开发流程,从而使开发更加快速高效。

    gulp 和 grunt 非常类似,但相比于 grunt 的频繁 IO 操作,gulp 的流操作,能更快地更便捷地完成构建工作。

    P2 安装

    可替换淘宝镜像:npm install cnpm -g --registry=https://registry.npm.taobao.org

    2.1 全局安装 gulp:

    $ npm install -g gulp
    

    查看是否正确安装:命令提示符执行gulp -v,出现版本号version 3.9.1即为正确安装。
    如果显示'glup' 不是内部或外部命令,也不是可运行的程序或批处理文件。,请确定你是否打对字,是gulp,而不是glup!!!这里我故意打错字你也发现不了。

    2.2 作为项目的开发依赖(devDependencies)安装:

    $ npm install --save-dev gulp
    

    P3 Gulp API整理

    gulp只有四个API: taskwatchsrc,和 dest

    3.1 gulp.task(name[, deps], fn)

    name:任务名;
    deps:StringArray(可选),一个包含任务列表的数组,这些任务会在你当前任务运行之前完成;
    fn:任务操作函数function() {}.
    //执行完one, two, three任务后再执行four
    gulp.task('four', ['one', 'two', 'three'], function() {
        return gulp.src(path)
            .pipe(someplugin());
        //或其他事
    });
    

    3.2 gulp.src(globs[, options])

    src方法是指定需要处理的源文件的路径,gulp借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入,gulp.src返回当前文件流至可用插件;

    globs:String 或 Array,需要处理的源文件匹配符路径

    **通配符路径匹配: **

    • src/a.js:指定具体文件
    • *:匹配所有文件 src/*.js(包含src下的所有js文件)
    • **:匹配0个或多个子文件夹 src/**/*.js(包含src的0个或多个子文件夹下的js文件);
    • {}:匹配多个属性 src/{a,b}.js(包含a.js和b.js文件) src/*.{jpg,png,gif}(src下的所有jpg/png/gif文件);
    • !:排除文件 !src/a.js(不包含src下的a.js文件);
    var gulp = require('gulp'),
        less = require('gulp-less');
     
    gulp.task('testLess', function () {
        //gulp.src('less/test/style.less')
        gulp.src(['less/**/*.less','!less/{extend,page}/*.less'])
            .pipe(less())
            .pipe(gulp.dest('./css'));
    });
    
    options: (可选) Object,有3个属性buffer、read、base
    • options.bufferBoolean 默认:true 设置为false,将返回file.content的流并且不缓冲文件,处理大文件时非常有用;
    • options.readBoolean 默认:true 设置false,将不执行读取文件操作,返回null;
    • options.baseString 设置输出路径以某个路径的某个组成部分为基础向后拼接,具体看下面示例:
    gulp.src('client/js/**/*.js') 
      .pipe(minify())
      .pipe(gulp.dest('build'));  // Writes 'build/somedir/somefile.js'
    
    gulp.src('client/js/**/*.js', { base: 'client' })
      .pipe(minify())
      .pipe(gulp.dest('build'));  // Writes 'build/js/somedir/somefile.js'
    

    异步任务支持
    只有当fn接受一个 callback,或者返回一个 promise 或 stream任务 才可以异步执行,且task默认以最大的并发数执行,即gulp 会一次性运行所有的 task 并且不做任何等待。

    
    //接受一个 callback
    var exec = require('child_process').exec;
    gulp.task('jekyll', function(cb) {
      // 编译 Jekyll
      exec('jekyll build', function(err) {
        if (err) return cb(err); // 返回 error
        cb(); // 完成 task
      });
    });
    
    //返回一个 stream
    gulp.task('somename', function() {
      var stream = gulp.src('client/**/*.js')
        .pipe(minify())
        .pipe(gulp.dest('build'));
      return stream;
    });
    
    //返回一个 promise
    var Q = require('q');
    gulp.task('somename', function() {
      var deferred = Q.defer();
      // 执行异步的操作
      setTimeout(function() {
        deferred.resolve();
      }, 1);
      return deferred.promise;
    });
    

    当然,如果你想要任务按照一定的顺序执行。例如有两个task,"one" 和 "two",在 "one" 中返回一个cb,或stream,promise,让系统知道什么时候它会执行完毕; 在 "two" 中添加提示告诉系统 "two" 需要依赖 "one" 完成,即下面给出的栗子:

    var gulp = require('gulp');
    
    // 返回一个 callback,因此系统可以知道它什么时候完成
    gulp.task('one', function(cb) {
        // 做一些事 -- 异步的或者其他的
        cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了
    });
    
    // 定义一个所依赖的 task 必须在这个 task 执行之前完成
    gulp.task('two', ['one'], function() {
        // 'one' 完成后
    });
    
    gulp.task('default', ['one', 'two']);
    

    3.3 gulp.dest(path[, options])

    dest方法是指定处理完后文件输出的路径

    path:String or Function 指定文件输出路径,或者定义函数返回文件输出路径亦可
    options:Object,有2个属性cwd、mode
    • options.cwdString 默认:process.cwd():当前脚本的工作目录的路径 当文件输出路径为相对路径将会用到
    • options.modeString 默认:0777 指定被创建文件夹的权限

    3.4 gulp.watch(glob [, opts], tasks)orgulp.watch(glob [, opts, cb])

    watch方法是用于监听文件变化,文件一修改就会执行指定的任务

    glob: String or StringArray 需要处理的源文件匹配符路径。
    opts: Object(可选) 具体参看 gaze
    tasks: StringArray 需要执行的任务的名称数组;
    cb(event): Function() 每次文件变化执行的回调函数;
    • event.type: String 发生的变动的类型:added, changed 或者 deleted
    • event.path: String 触发了该事件的文件的路径。

    P4 新建gulpfile.js文件

    说明:gulpfile.js是gulp项目的配置文件,是位于项目根目录的普通js文件(其实将gulpfile.js放入其他文件夹下亦可)

    我们将要使用Gulp插件来完成我们以下任务:

    • sass的编译(gulp-sass)
    • 自动添加css前缀(gulp-autoprefixer)
    • 压缩css(gulp-minify-css)
    • js代码校验(gulp-jshint)
    • 合并js文件(gulp-concat)
    • 压缩js代码(gulp-uglify)
    • 压缩图片(gulp-imagemin)
    • 自动刷新页面(gulp-livereload)
    • 图片缓存,只有图片替换了才压缩(gulp-cache)
    • 更改提醒(gulp-notify)
    • 修改文件名(gulp-rename)

    安装这些插件需要运行如下命令:

    npm install gulp-sass gulp-autoprefixer gulp-minify-css gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache --save-dev
    
    //成功安装后在package.json中出现版本信息
    {
    "devDependencies": {
        "gulp": "^3.9.1",
        "gulp-autoprefixer": "^3.1.1",
        "gulp-cache": "^0.4.6",
        "gulp-concat": "^2.6.1",
        "gulp-imagemin": "^3.2.0",
        "gulp-jshint": "^2.0.4",
        "gulp-livereload": "^3.8.1",
        "gulp-minify-css": "^1.2.4",
        "gulp-notify": "^3.0.0",
        "gulp-rename": "^1.2.2",
        "gulp-sass": "^3.1.0",
        "gulp-uglify": "^2.1.2"
      }
    }
    

    更多插件请点这里 gulp.js插件

    4.1 加载插件:

    // Load plugins
    var gulp = require('gulp'),
        sass = require('gulp-sass'),
        autoprefixer = require('gulp-autoprefixer'),
        minifycss = require('gulp-minify-css'),
        jshint = require('gulp-jshint'),
        uglify = require('gulp-uglify'),
        imagemin = require('gulp-imagemin'),
        rename = require('gulp-rename'),
        concat = require('gulp-concat'),
        notify = require('gulp-notify'),
        cache = require('gulp-cache'),
        livereload = require('gulp-livereload');
    

    4.2 建立任务:

    4.2.1 编译sass、自动添加css前缀和压缩

    首先我们编译sass,添加前缀,保存到我们指定的目录下面,还没结束,我们还要压缩,给文件添加 .min 后缀再输出压缩文件到指定目录,最后提醒任务完成了:

    // Styles任务
    gulp.task('styles', function() {
        //编译sass
        return gulp.src('stylesheets/main.scss')
            .pipe(sass())
            //添加前缀
            .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
            //保存未压缩文件到我们指定的目录下面
            .pipe(gulp.dest('stylesheets'))
            //给文件添加.min后缀
            .pipe(rename({ suffix: '.min' }))
            //压缩样式文件
            .pipe(minifycss())
            //输出压缩文件到指定目录
            .pipe(gulp.dest('assets'))
            //提醒任务完成
            .pipe(notify({ message: 'Styles task complete' }));
    });
    

    4.2.2 js代码校验、合并和压缩

    // Scripts任务
    gulp.task('scripts', function() {
        //js代码校验
        return gulp.src('javascripts/*.js')
            .pipe(jshint())
            .pipe(jshint.reporter('default'))
            //js代码合并
            .pipe(concat('all.js'))
            //给文件添加.min后缀
            .pipe(rename({ suffix: '.min' }))
            //压缩脚本文件
            .pipe(uglify())
            //输出压缩文件到指定目录
            .pipe(gulp.dest('assets'))
            //提醒任务完成
            .pipe(notify({ message: 'Scripts task complete' }));
    });
    

    4.2.3 图片压缩

    // Images
    gulp.task('images', function() {
        return gulp.src('images/*')
            .pipe(cache(imagemin({ 
                optimizationLevel: 3, //类型:Number默认:3取值范围:0-7(优化等级)
                progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
                interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染
                multipass: true //类型:Boolean 默认:false 多次优化svg直到完全优化
                })))
            .pipe(gulp.dest('images'))
            .pipe(notify({ message: 'Images task complete' }));
    });
    

    4.2.4 事件监听

    // Watch
    gulp.task('watch', function() {
        // Watch .scss files
        gulp.watch('stylesheets/*.scss', ['styles']);
        // Watch .js files
        gulp.watch('javascripts/*.js', ['scripts']);
        // Watch image files
        gulp.watch('images/*', ['images']);
        // Create LiveReload server
        livereload.listen();
        // Watch any files in assets/, reload on change
        gulp.watch(['assets/*']).on('change', livereload.changed);
    });
    

    4.2.5 定义默认任务

    栗子里的第二个参数是一个包含任务列表的数组,这些任务会在你当前任务运行之前完成。

    gulp.task('default', ['styles', 'scripts', 'images', 'watch'], function() {
        console.log('Everthing is done!');
    });
    

    P5 运行gulp

    5.1 命令提示符执行

    • 命令提示符执行gulp 任务名称, 如gulp styles
    • 当执行gulp defaultgulp将会调用default任务里的所有任务

    5.2 使用WebStorm运行gulp任务

    将项目导入WebStorm,右键gulpfile.js 选择“Show Gulp Tasks”打开Gulp窗口,若出现“No task found”,选择右键”Reload tasks”,双击运行即可。

    参考文档

    一点
    gulp API 文档
    前端构建工具gulp入门教程1
    前端构建工具gulp入门教程2

    相关文章

      网友评论

      本文标题:Gulp学习笔记

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