gulp入門之常見處理方式(三)

整合 streams 來處理錯誤

默認狀況下,在 stream 中發生一個錯誤的話,它會被直接拋出,除非已經有一個時間監聽器監聽着 error時間。 這在處理一個比較長的管道操做的時候會顯得比較棘手。html

這裏是一個在 gulpfile 中使用它的例子:node

var combiner = require('stream-combiner2');
var uglify = require('gulp-uglify');
var gulp = require('gulp');

gulp.task('test', function() {
  var combined = combiner.obj([
    gulp.src('bootstrap/js/*.js'),
    uglify(),
    gulp.dest('public/bootstrap')
  ]);

  // 任何在上面的 stream 中發生的錯誤,都不會拋出,
  // 而是會被監聽器捕獲
  combined.on('error', console.error.bind(console));

  return combined;
});

刪除文件和文件夾

最好的一個選擇就是使用一個原生的 node 模塊。git

$ npm install --save-dev gulp del

假想有以下的文件結構:github

.
├── dist
│   ├── report.csv
│   ├── desktop
│   └── mobile
│       ├── app.js
│       ├── deploy.json
│       └── index.html
└── src

在 gulpfile 中,咱們但願在運行咱們的編譯任務以前,將 mobile 文件的內容先清理掉:npm

var gulp = require('gulp');
var del = require('del');

gulp.task('clean:mobile', function (cb) {
  del([
    'dist/report.csv',
    // 這裏咱們使用一個通配模式來匹配 `mobile` 文件夾中的全部東西
    'dist/mobile/**/*',
    // 咱們不但願刪掉這個文件,因此咱們取反這個匹配模式
    '!dist/mobile/deploy.json'
  ], cb);
});

gulp.task('default', ['clean:mobile']);

 在管道中刪除文件

你可能須要在管道中將一些處理過的文件刪除掉。json

咱們使用 vinyl-paths 模塊來簡單地獲取 stream 中每一個文件的路徑,而後傳給 del 方法。gulp

$ npm install --save-dev gulp del vinyl-paths

假想有以下的文件結構:bootstrap

.
├── tmp
│   ├── rainbow.js
│   └── unicorn.js
└── dist
var gulp = require('gulp');
var stripDebug = require('gulp-strip-debug'); // 僅用於本例作演示
var del = require('del');
var vinylPaths = require('vinyl-paths');

gulp.task('clean:tmp', function () {
  return gulp.src('tmp/*')
    .pipe(stripDebug())
    .pipe(gulp.dest('dist'))
    .pipe(vinylPaths(del));
});

gulp.task('default', ['clean:tmp']);

只有在已經使用了其餘的插件以後才須要這樣作,不然,請直接使用 gulp.src 來代替。api

增量編譯打包,包括處理整所涉及的全部文件

在作增量編譯打包的時候,有一個比較麻煩的事情,那就是你經常但願操做的是 全部 處理過的文件,而不單單是單個的文件。舉個例子,你想要只對更改的文件作代碼 lint 操做,以及一些模塊封裝的操做,而後將他們與其餘已經 lint 過的,以及已經進行過模塊封裝的文件合併到一塊兒。若是不用到臨時文件的話,這將會很是困難。app

使用 gulp-cached 以及 gulp-remember 來解決這個問題。

var gulp = require('gulp');
var header = require('gulp-header');  //給文本文件頭部追加內容
var footer = require('gulp-footer');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint'); //js代碼校驗
var cached = require('gulp-cached');
var remember = require('gulp-remember'); // is a gulp plugin that remembers files that have passed through it.  adds all the files it has ever seen back into the stream.

var scriptsGlob = 'src/**/*.js';

gulp.task('scripts', function() {
  return gulp.src(scriptsGlob)
      .pipe(cached('scripts'))        // 只傳遞更改過的文件   A temp file based caching proxy task for gulp.
      .pipe(jshint())                 // 對這些更改過的文件作一些特殊的處理...
      .pipe(header('(function () {')) // 好比 jshinting ^^^
      .pipe(footer('})();'))          // 增長一些相似模塊封裝的東西
      .pipe(remember('scripts'))      // 把全部的文件放回 stream
      .pipe(concat('app.js'))         // 作一些須要全部文件的操做
      .pipe(gulp.dest('public/'));
});

gulp.task('watch', function () {
  var watcher = gulp.watch(scriptsGlob, ['scripts']); // 監視與 scripts 任務中一樣的文件
  watcher.on('change', function (event) {
    if (event.type === 'deleted') {                   // 若是一個文件被刪除了,則將其忘記
      delete cached.caches.scripts[event.path];       // gulp-cached 的刪除 api
      remember.forget('scripts', event.path);         // gulp-remember 的刪除 api
    }
  });
});gulp-remembergulp-remember

 

在 gulp 中運行 Mocha 測試

運行全部的測試用例

// npm install gulp gulp-mocha

var gulp = require('gulp');
var mocha = require('gulp-mocha');

gulp.task('default', function() {
  return gulp.src(['test/test-*.js'], { read: false })
    .pipe(mocha({
      reporter: 'spec',
      globals: {
        should: require('should')
      }
    }));
});

在文件改動時候運行 mocha 測試用例

// npm install gulp gulp-mocha gulp-util

var gulp = require('gulp');
var mocha = require('gulp-mocha');
var gutil = require('gulp-util');

gulp.task('mocha', function() {
    return gulp.src(['test/*.js'], { read: false })
        .pipe(mocha({ reporter: 'list' }))
        .on('error', gutil.log);
});

gulp.task('watch-mocha', function() {
    gulp.watch(['lib/**', 'test/**'], ['mocha']);
});

僅僅傳遞更改過的文件

默認狀況下,每次運行時候全部的文件都會傳遞並經過整個管道。經過使用 gulp-changed 能夠只讓更改過的文件傳遞過管道。這能夠大大加快連續屢次的運行。

// npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify

var gulp = require('gulp');
var changed = require('gulp-changed');
var jscs = require('gulp-jscs');
var uglify = require('gulp-uglify');

// 咱們在這裏定義一些常量以供使用
var SRC = 'src/*.js';
var DEST = 'dist';

gulp.task('default', function() {
    return gulp.src(SRC)
        // `changed` 任務須要提早知道目標目錄位置
        // 才能找出哪些文件是被修改過的
        .pipe(changed(DEST))
        // 只有被更改過的文件纔會經過這裏
        .pipe(jscs())
        .pipe(uglify())
        .pipe(gulp.dest(DEST));
});

從命令行傳遞參數

// npm install --save-dev gulp gulp-if gulp-uglify minimist

var gulp = require('gulp');
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');

var minimist = require('minimist');

var knownOptions = {
  string: 'env',
  default: { env: process.env.NODE_ENV || 'production' }
};

var options = minimist(process.argv.slice(2), knownOptions);

gulp.task('scripts', function() {
  return gulp.src('**/*.js')
    .pipe(gulpif(options.env === 'production', uglify())) // 僅在生產環境時候進行壓縮
    .pipe(gulp.dest('dist'));
});
$ gulp scripts --env development
相關文章
相關標籤/搜索