Gulp 新一代流行的任务自动管理工具 - 文章教程

Gulp 新一代流行的任务自动管理工具

发布于 2021-11-25 字数 22193 浏览 835 评论 0

官网:http://gulpjs.com

API:https://github.com/gulpjs/gulp/blob/master/docs/API.md

Gulp 与 Grunt 一样,也是一个自动任务运行器。它充分借鉴了 Unix 操作系统的管道(pipe)思想,很多人认为,在操作上,它要比 Grunt 简单。

安装

Gulp 需要全局安装,然后再在项目的开发目录中安装为本地模块。先进入项目目录,运行下面的命令。

npm install -g gulp

// 将gulp安装到项目本地
npm install --save-dev gulp
// 安装插件
npm install --save-dev gulp-uglify
npm install gulp-jshint gulp-sass gulp-concat gulp-uglify gulp-rename --save-dev

gulpfile.js

项目根目录中的 gulpfile.js,是 Gulp 的配置文件。

var gulp = require('gulp');
  gulp.task('default', function() {
});

下面就是一个典型的 gulpfile.js 文件。

var gulp = require('gulp'),
    uglify = require('gulp-uglify');

gulp.task('minify', function() {
    gulp.src('js/app.js')
        .pipe(uglify())
        .pipe(gulp.dest('build'))
});

gulp 模块的 task 方法指定任务。task 方法有两个参数,第一个是任务名,第二个是任务函数。

在任务函数中:

使用 gulp 模块的 src 方法,指定所要处理的文件,然后使用 pipe 方法,将上一步的输出转为当前的输入,进行链式处理。

从上面的例子中可以看到,gulp 充分使用了“管道”思想,就是一个数据流(stream):src 方法读入文件产生数据流,dest 方法将数据流写入文件,中间是一些中间步骤,每一步都对数据流进行一些处理。

  • gulp.src(‘js/app.js’):指定所要处理的文件
  • pipe():将上一步的输出转为当前的输入,进行链式处理。
  • uglify():压缩源码
  • gulp.dest(‘build’):将上一步的输出写入本地文件

这里是 build.js(代码中省略了后缀名 js)。

// 引入 gulp
var gulp = require('gulp');

// 引入组件
var jshint = require('gulp-jshint');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

// 检查脚本:Link任务会检查js/目录下得js文件有没有报错或警告。
gulp.task('lint', function() {
    gulp.src('./js/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'));
});

// 编译Sass:Sass任务会编译scss/目录下的scss文件,并把编译完成的css文件保存到/css目录中。
gulp.task('sass', function() {
    gulp.src('./scss/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./css'));
});

// 合并,压缩文件:scripts任务会合并js/目录下得所有得js文件并输出到dist/目录,然后gulp会重命名、压缩合并的文件,也输出到dist/目录。
gulp.task('scripts', function() {
    gulp.src('./js/*.js')
        .pipe(concat('all.js'))
        .pipe(gulp.dest('./dist'))
        .pipe(rename('all.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('./dist'));
});

// 默认任务:这时,我们创建了一个基于其他任务的default任务。使用.run()方法关联和运行我们上面定义的任务,使用.watch()方法去监听指定目录的文件变化,当有文件变化时,会运行回调定义的其他任务。
gulp.task('default', function() {
    gulp.run('lint', 'sass', 'scripts');

    // 监听文件变化
    gulp.watch('./js/*.js', function() {
        gulp.run('lint', 'sass', 'scripts');
    });
});

现在,回到命令行,可以直接运行 gulp 任务了 gulp 这将执行定义的 default 任务,换言之,这和以下的命令式同一个意思 gulp default

模块加载

1.gulpfile.js 中一一加载模块

gulpfile.js

var gulp = require('gulp'),
    jshint = require('gulp-jshint'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat');

gulp.task('js', function() {
    return gulp.src('js/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(uglify())
        .pipe(concat('app.js'))
        .pipe(gulp.dest('build'));
});

2.使用 gulp-load-plugins 自动载入所有已安装的模块

使用 gulp-load-plugins 模块,可以加载 package.json 文件中所有的gulp模块。

package.json

{
    "devDependencies": {
        "gulp-concat": "~2.2.0",
        "gulp-uglify": "~0.2.1",
        "gulp-jshint": "~1.5.1",
        "gulp": "~3.5.6"
    }
}

gulpfile.js

var gulp = require('gulp'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    plugins = gulpLoadPlugins();

gulp.task('js', function() {
    return gulp.src('js/*.js')
        .pipe(plugins.jshint())
        .pipe(plugins.jshint.reporter('default'))
        .pipe(plugins.uglify())
        .pipe(plugins.concat('app.js'))
        .pipe(gulp.dest('build'));
});

gulp.src()

gulp 模块的 src 方法,用于产生数据流。它的参数表示所要处理的文件,一般有以下几种形式。

  • js/app.js:指定确切的文件名。
  • js/.js:某个目录所有后缀名为 js 的文件。
  • js/**/*.js:某个目录及其所有子目录中的所有后缀名为 js 的文件。
  • !js/app.js:除了 js/app.js 以外的所有文件。
  • *.+(js|css):匹配项目根目录下,所有后缀名为 js 或 css 的文件。
  • [‘js/*/*.js’, ‘!js/**/*.min.js’]:还可以是一个数组,用来指定多个成员。

gulp.task()

gulp 模块的 task 方法,用于定义具体的任务。它的第一个参数是任务名,第二个参数是任务函数

非常简单的任务函数:

gulp.task('greet', function() {
    console.log('Hello world!');
});

task 方法还可以指定按顺序运行的一组任务:

gulp.task('css', function() {
    console.log('css...');
});

gulp.task('js', function() {
    console.log('js...');
});

gulp.task('imgs', function() {
    console.log('imgs...');
});

gulp.task('build', ['css', 'js', 'imgs']);

上面代码先指定 build 任务,它按次序由 css、js、imgs 三个任务所组成。注意,由于每个任务都是异步调用,所以没有办法保证js任务的开始运行的时间,正是css任务运行结束。

任务严格按次序运行:

gulp.task('greet', function() {
    console.log('Hello world!');
});

gulp.task('css', ['greet'], function() {
    console.log('css...');
});

gulp.task('js', function() {
    console.log('js...');
});

gulp.task('build', ['css', 'js']);

上面代码表明,css 任务依赖 greet 任务,所以 css 一定会在 greet 运行完成后再运行。

默认任务:

gulp.task('default', function() {
    // Your default task
});

如果一个任务的名字为 default,就表明它是 默认任务,在命令行直接输入 gulp 命令,就会运行该任务。

gulp.watch()

gulp 模块的 watch 方法,用于指定需要监视的文件。一旦这些文件发生变动,就运行指定任务。

watch 方法

gulp.task('watch', function() {
    gulp.watch('templates/*.tmpl.html', ['build']);
});

上面代码指定,一旦 templates 目录中的模板文件发生变化,就运行build任务。

watch 方法也可以用回调函数,代替指定的任务。

gulp.watch('templates/*.tmpl.html', function(event) {
    console.log('Event type: ' + event.type);
    console.log('Event path: ' + event.path);
});

另一种写法是 watch 方法所监控的文件发生变化时(修改、增加、删除文件),会触发 change 事件。可以对 change 事件指定回调函数。

var watcher = gulp.watch('templates/*.tmpl.html', ['build']);

watcher.on('change', function(event) {
    console.log('Event type: ' + event.type);
    console.log('Event path: ' + event.path);
});

除了change事件,watch 方法还可能触发以下事件:

  • end:回调函数运行完毕时触发。
  • error:发生错误时触发。
  • ready:当开始监听文件时触发。
  • nomatch:没有匹配的监听文件时触发。
  • watcher对象还包含其他一些方法。
  • watcher.end():停止 watcher对象,不会再调用任务或回调函数。
  • watcher.files():返回 watcher对象监视的文件。
  • watcher.add(glob):增加所要监视的文件,它还可以附件第二个参数,表示回调函数。
  • watcher.remove(filepath):从 watcher对象中移走一个监视的文件。

模块

  • gulp-load-plugins 模块(如上)
  • gulp-livereload:模块用于自动刷新浏览器,反映出源码的最新变化。它除了模块以外,还需要在浏览器中安装插件,用来配合源码变化。
var gulp = require('gulp'),
    less = require('gulp-less'),
    livereload = require('gulp-livereload'),
    watch = require('gulp-watch');

gulp.task('less', function() {
    gulp.src('less/*.less')
        .pipe(watch())
        .pipe(less())
        .pipe(gulp.dest('css'))
        .pipe(livereload());
});

上面代码监视 less 文件,一旦编译完成,就自动刷新浏览器。流程:

  • 自动载入(gulp-load-plugins)
  • 编译Sass (gulp-ruby-sass)
  • Autoprefixer (gulp-autoprefixer)
  • 缩小化(minify)
  • CSS (gulp-minify-css)
  • JSHint (gulp-jshint)
  • 拼接 (gulp-concat)
  • 丑化(Uglify) (gulp-uglify)
  • 图片压缩 (gulp-imagemin)
  • 即时重整(LiveReload) (gulp-livereload)
  • 清理档案 (gulp-clean)
  • 图片快取,只有更改过得图片会进行压缩 (gulp-cache)
  • 更动通知 (gulp-notify)

用到的模块:

  • gulp-less : less
  • gulp-ruby-sass : 支持 sass
  • gulp-minify-css : 压缩
  • css gulp-jshint : 检查 js
  • gulp-uglify : 压缩 js
  • gulp-concat : 合并文件
  • gulp-rename : 重命名文件
  • gulp-htmlmin : 压缩 html
  • gulp-clean : 清空文件夹

执行下列指令来安装这些外挂:

$ npm install gulp-ruby-sass gulp-autoprefixer gulp-minify-css gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-clean gulp-notify gulp-rename gulp-livereload gulp-cache --save-dev

指令将会安装必要的外挂,并纪录于 package.json 内的 devDependencies 物件。完整的 gulp 外挂清单可以在这裡找到。 http://gratimax.net/search-gulp-plugins

配置事例

示例配置:Gulp 实现完整的 SASS 自动编译并刷新网页

// Include gulp
var gulp = require('gulp');

// Include Our Plugins
var sass = require('gulp-sass');

var lr = require('tiny-lr'),
    refresh = require('gulp-livereload'),
    server = lr();


// Task SASS
gulp.task('sass', function() {
    gulp.src([
        'scss/**/*.scss',
        '!scss/**/_*.scss'
    ])
        .pipe(sass({
            includePaths: ['scss']
        }))
        .pipe(gulp.dest('css'))
        .pipe(refresh(server));
});


gulp.task('refresh', function() {
    gulp.src([
        '**/*.html',
        '**/*.php'
    ])
        .pipe(refresh(server));
});


// Task: default
gulp.task('default', function() {
    gulp.run('sass');

    server.listen(35729, function(error) {
        if (error) return console.log(error);

        gulp.watch([
            'scss/**',
            'img/**'
        ], function(event) {
            gulp.run('sass');
        });

        gulp.watch([
            '**/*.html',
            '**.php'
        ], function(event) {
            gulp.run('refresh');
        });
    });
});

gulpfile.js

var gulp = require('gulp');

// 引入组件
var less = require('gulp-less'), // less
  minifycss = require('gulp-minify-css'), // CSS压缩
  uglify = require('gulp-uglify'), // js压缩
  concat = require('gulp-concat'), // 合并文件
  rename = require('gulp-rename'), // 重命名
  clean = require('gulp-clean'); //清空文件夹

// less解析
gulp.task('build-less', function() {
  gulp.src('./javis/static/less/lib/s-production.less')
    .pipe(less())
    .pipe(gulp.dest('./javis/static/build/css/lib/'))

  gulp.src('./javis/static/less/lib/s-skins.less')
    .pipe(less())
    .pipe(gulp.dest('./javis/static/build/css/lib/'))

  gulp.src('./javis/static/less/lib/s/s.less')
    .pipe(less())
    .pipe(gulp.dest('./javis/static/build/css/lib/'))

  gulp.src('./javis/static/less/*.less')
    .pipe(less())
    .pipe(gulp.dest('./javis/static/build/css/'))
});

// 合并、压缩、重命名css
gulp.task('stylesheets', ['build-less'], function() {
  // 注意这里通过数组的方式写入两个地址,仔细看第一个地址是css目录下的全部css文件,第二个地址是css目录下的areaMap.css文件,但是它前面加了!,这个和.gitignore的写法类似,就是排除掉这个文件.
  gulp.src(['./javis/static/build/css/*.css', '!./javis/static/build/css/areaMap.css'])
    .pipe(concat('all.css'))
    .pipe(gulp.dest('./javis/static/build/css/'))
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(minifycss())
    .pipe(gulp.dest('./javis/static/build/css'));
});

// 合并,压缩js文件
gulp.task('javascripts', function() {
  gulp.src('./javis/static/js/*.js')
    .pipe(concat('all.js'))
    .pipe(gulp.dest('./javis/static/build/js'))
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(uglify())
    .pipe(gulp.dest('./javis/static/build/js'));
});

// 清空图片、样式、js
gulp.task('clean', function() {
  return gulp.src(['./javis/static/build/css/all.css', './javis/static/build/css/all.min.css'], {
    read: false
  })
    .pipe(clean({
      force: true
    }));
});

// 将bower的库文件对应到指定位置
gulp.task('buildlib', function() {

  gulp.src('./bower_components/angular/angular.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/angular/angular.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/bootstrap/dist/js/bootstrap.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/jquery/dist/jquery.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/angular-route/angular-route.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/angular-animate/angular-animate.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/angular-bootstrap/ui-bootstrap.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  gulp.src('./bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js')
    .pipe(gulp.dest('./javis/static/build/js/'))

  //--------------------------css-------------------------------------

  gulp.src('./javis/static/less/fonts/*')
    .pipe(gulp.dest('./javis/static/build/css/fonts/'))

  gulp.src('./bower_components/bootstrap/fonts/*')
    .pipe(gulp.dest('./javis/static/build/css/fonts/'))

  gulp.src('./bower_components/bootstrap/dist/css/bootstrap.min.css')
    .pipe(gulp.dest('./javis/static/build/css/lib'))

});

// 定义develop任务在日常开发中使用
gulp.task('develop', function() {
  gulp.run('buildlib', 'build-less', 'javascripts', 'stylesheets');

  gulp.watch('./javis/static/less/*.less', ['build-less']);
});

// 定义一个prod任务作为发布或者运行时使用
gulp.task('prod', function() {
  gulp.run('buildlib', 'build-less', 'stylesheets', 'javascripts');

  // 监听.less文件,一旦有变化,立刻调用build-less任务执行
  gulp.watch('./javis/static/less/*.less', ['build-less']);
});

// gulp命令默认启动的就是default认为,这里将clean任务作为依赖,也就是先执行一次clean任务,流程再继续.
gulp.task('default', ['clean'], function() {
  gulp.run('develop');
});

gulp 与 Grunt

gulpfile.js

/*!
 * gulp
 * $ npm install gulp-ruby-sass gulp-autoprefixer gulp-minify-css gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache del --save-dev
 */

// Load plugins
var gulp = require('gulp'),
  sass = require('gulp-ruby-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'),
  del = require('del');

// Styles
gulp.task('styles', function() {
  return gulp.src('src/styles/main.scss')
    .pipe(sass({
      style: 'expanded',
    }))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('dist/styles'))
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(minifycss())
    .pipe(gulp.dest('dist/styles'))
    .pipe(notify({
      message: 'Styles task complete'
    }));
});

// Scripts
gulp.task('scripts', function() {
  return gulp.src('src/scripts/**/*.js')
    .pipe(jshint('.jshintrc'))
    .pipe(jshint.reporter('default'))
    .pipe(concat('main.js'))
    .pipe(gulp.dest('dist/scripts'))
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/scripts'))
    .pipe(notify({
      message: 'Scripts task complete'
    }));
});

// Images
gulp.task('images', function() {
  return gulp.src('src/images/**/*')
    .pipe(cache(imagemin({
      optimizationLevel: 3,
      progressive: true,
      interlaced: true
    })))
    .pipe(gulp.dest('dist/images'))
    .pipe(notify({
      message: 'Images task complete'
    }));
});

// Clean
gulp.task('clean', function(cb) {
  del(['dist/assets/css', 'dist/assets/js', 'dist/assets/img'], cb)
});

// Default task
gulp.task('default', ['clean'], function() {
  gulp.start('styles', 'scripts', 'images');
});

// Watch
gulp.task('watch', function() {

  // Watch .scss files
  gulp.watch('src/styles/**/*.scss', ['styles']);

  // Watch .js files
  gulp.watch('src/scripts/**/*.js', ['scripts']);

  // Watch image files
  gulp.watch('src/images/**/*', ['images']);

  // Create LiveReload server
  livereload.listen();

  // Watch any files in dist/, reload on change
  gulp.watch(['dist/**']).on('change', livereload.changed);

});

Gruntfile.js


/*!
 * Grunt
 * $ npm install grunt-contrib-uglify grunt-autoprefixer grunt-contrib-cssmin grunt-contrib-imagemin grunt-contrib-sass grunt-contrib-watch grunt-contrib-concat grunt-contrib-clean grunt-contrib-jshint grunt-notify --save-dev
 */

module.exports = function(grunt) {

  grunt.initConfig({

    // Sass
    sass: {
      dist: {
        options: {
          style: 'expanded'
        },
        files: {
          'dist/styles/main.css': 'src/styles/main.scss'
        }
      }
    },

    // Autoprefix
    autoprefixer: {
      options: {
        browsers: [
          'last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'
        ]
      },
      dist: {
        src: 'dist/styles/main.css'
      }
    },

    // CSS minify
    cssmin: {
      dist: {
        files: {
          'dist/styles/main.min.css': 'dist/styles/main.css'
        }
      }
    },

    // JShint
    jshint: {
      files: ['src/scripts/**/*.js'],
      options: {
        jshintrc: '.jshintrc'
      }
    },

    // Concat
    concat: {
      js: {
        src: ['src/scripts/**/*.js'],
        dest: 'dist/scripts/main.js'
      },
    },

    // Uglify
    uglify: {
      dist: {
        src: 'dist/scripts/main.js',
        dest: 'dist/scripts/main.min.js'
      },
    },

    // Imagemin
    imagemin: {
      dist: {
        options: {
          optimizationLevel: 3,
          progressive: true,
          interlaced: true
        },
        files: [{
          expand: true,
          cwd: 'src/images',
          src: ['**/*.{png,jpg,gif}'],
          dest: 'dist/images'
        }]
      }
    },

    // Clean
    clean: {
      build: ['dist/styles', 'dist/scripts', 'dist/images']
    },

    // Notify
    notify: {
      styles: {
        options: {
          message: 'Styles task complete',
        }
      },
      scripts: {
        options: {
          message: 'Scripts task complete',
        }
      },
      images: {
        options: {
          message: 'Images task complete',
        }
      },
    },

    // Watch
    watch: {
      styles: {
        files: 'src/styles/**/*.scss',
        tasks: ['sass', 'autoprefixer', 'cssmin', 'notify:styles'],
      },
      scripts: {
        files: 'src/scripts/**/*.js',
        tasks: ['concat', 'uglify', 'notify:scripts'],
      },
      images: {
        files: 'src/images/**/*',
        tasks: ['imagemin', 'notify:images'],
      },
      livereload: {
        options: {
          livereload: true
        },
        files: [
          'dist/styles/**/*.css',
          'dist/scripts/**/*.js',
          'dist/images/**/*'
        ]
      }
    }
  });

  // Default task
  grunt.registerTask('default', [
    'jshint',
    'clean',
    'concat',
    'uglify',
    'sass',
    'autoprefixer',
    'cssmin',
    'imagemin'
  ]);

  // Load plugins
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-autoprefixer');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-notify');

};

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

风苍溪

这个人比较懒,什么都没有填写!

0 文章
0 评论
656 人气
更多

推荐作者

qianbiandeboy

文章 0 评论 0

少女净妖师

文章 2 评论 0

zangqw

文章 0 评论 0

qq_7HKsl

文章 0 评论 0

伪装你

文章 1 评论 0