gulp消除已压缩文件思绪

gulp默许消除语法的弊病

有个时刻我们须要时用gulp消除已紧缩过的js,css等。假如以紧缩文件是以”.min.js”之类定名范例的还好,假如不是呢?而且另有其他一些场景也会有须要。
gulp默许支撑glob花样,消除语法为!
举几个例子:
消除目次

gulp.src([
    baseDir + '/**',                              // Include all
    '!' + baseDir + '/excl1{,/**}',               // Exclude excl1 dir
    '!' + baseDir + '/excl2/**/!(.gitignore)',    // Exclude excl2 dir, except .gitignore
], { dot: true });

消除文件:

gulp.src(['css/**/!(ignore.css)*.css'])
gulp.src([
      '!css/ignnore.css',
      'css/*.css'
    ])

这确切能够消除一些文件。然则还不算壮大,不能满足一些庞杂的场景。
而且还存在如许一个题目:当我有一个jquery.min.js,在紧缩js时,我不想对它举行紧缩,但同时我又想将其输出到dist目次下。纯真采纳上面这类体式格局须要”曲线救国”,场景以下:

gulp.task('jsmin', function (cb) {
        return gulp.src([SRC_DIR+'/**/*.js',,'!'+SRC_DIR+'/**/*.min.js'])
        .pipe(sourcemaps.init())
        .pipe(uglify({mangle: {except: ['require' ,'exports' ,'module' ,'$']}})) //消除殽杂关键字
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(DEST_DIR));

});

很遗憾地通知你,*.min.js并没有被拷贝到DEST_DIR,固然曲线救国能够以下:

gulp.task('copy', () =>{
    return gulp.src([SRC_DIR+'/**/*.min.js'])
        .pipe(gulp.dest(DEST_DIR));
    }
);

然则,这不是很文雅。而且上面我们也说了只是采纳glob语法对文件举行消除不适用于庞杂的场景。

Vinyl文件体系

细致申明,请参考探讨Gulp的Stream
如今这里贴出,背面会申明其目标。
虽然Gulp运用的是Stream,但却不是一般的Node Stream,实际上,Gulp(以及Gulp插件)用的应当叫做Vinyl File Object Stream。
这里的Vinyl,是一种假造文件花样。Vinyl主要用两个属性来形貌文件,它们分别是途径(path)及内容(contents)。详细来说,Vinyl并不神奇,它仍然是JavaScript Object。Vinyl官方给了如许的示例:

var File = require('vinyl');
var coffeeFile = new File({
  cwd: "/",
  base: "/test/",
  path: "/test/file.coffee",
  contents: new Buffer("test = 123")
});

从这段代码能够看出,Vinyl是Object,path和contents也恰是这个Object的属性。

解决方案形貌:

能够采纳gulp插件来完成更加壮大的消除。主要有以下几个插件:
gulp-ignore,支撑经由过程boolean,stat对象,函数来推断是不是消除与包含。推断函数接收一个Vinyl文件对象,返回一个boolean值。
gulp-filter,支撑glob形式、函数过滤,以及过滤后恢复
gulp-if,支撑前提推断(支撑函数前提)来掌握相干流程。
下面详细申明怎样运用

gulp-ignore:

API
exclude(condition [, minimatchOptions])
Exclude files whose file.path matches, include everything else
include(condition [, minimatchOptions])
Include files whose file.path matches, exclude everything else
参数申明:
condition:范例能够为 boolean or stat object or function
当为函数是接收一个vinyl file返回boolean值

下面贴出官方例子:

var gulpIgnore = require('gulp-ignore');
var uglify = require('gulp-uglify');
var jshint = require('gulp-jshint');

var condition = './gulpfile.js';

gulp.task('task', function() {
  gulp.src('./**/*.js')
    .pipe(jshint())
    .pipe(gulpIgnore.exclude(condition))
    .pipe(uglify())
    .pipe(gulp.dest('./dist/'));
});
var gulpIgnore = require('gulp-ignore');
var uglify = require('gulp-uglify');
var jshint = require('gulp-jshint');

var condition = './public/**.js';

gulp.task('task', function() {
  gulp.src('./**/*.js')
    .pipe(jshint())
    .pipe(gulpIgnore.include(condition))
    .pipe(uglify())
    .pipe(gulp.dest('./dist/'));
});

完成:

var condition = function(f){
    if(f.path.endswith('.min.js')){
        return true;
    }
    return false
};

gulp.task('jsmin', function (cb) {
        return gulp.src([SRC_DIR+'/**/*.js'])
        .pipe(gulpIgnore.exclude(condition))
        .pipe(sourcemaps.init())
        .pipe(uglify({mangle: {except: ['require' ,'exports' ,'module' ,'$']}})) //消除殽杂关键字
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(DEST_DIR));

});

长处:很明显,你能够在前提函数中做你想做的任何事情,包含运用正则表达式等。
瑕玷:和默许状况一样,不支撑被消除文件的拷贝

gulp-if

和gulp-ignore作者是统一个人
API:
gulpif(condition, stream [, elseStream, [, minimatchOptions]])
gulp-if will pipe data to stream whenever condition is truthy.
If condition is falsey and elseStream is passed, data will pipe to elseStream
这就类似于三目运算符,功能用伪代码示意就是if condition then stream(data) else elseStream(data)
After data is piped to stream or elseStream or neither, data is piped down-stream.

参数申明:
condition 与gulp-ignore一致。
Type: boolean or stat object or function that takes in a vinyl file and returns a boolean or RegularExpression that works on the file.path

stream
Stream for gulp-if to pipe data into when condition is truthy.

elseStream
Optional, Stream for gulp-if to pipe data into when condition is falsey.

minimatchOptions
Optional, if it’s a glob condition, these options are passed to minimatch.

官方例子:

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

var condition = true; // TODO: add business logic

gulp.task('task', function() {
  gulp.src('./src/*.js')
    .pipe(gulpif(condition, uglify()))
    .pipe(gulp.dest('./dist/'));
});

Only uglify the content if the condition is true, but send all the files to the dist folder
仅紧缩相符前提的文件,丹斯一切文件(包含不相符前提的)都邑被发送到dist目次。

完成:

var condition = function(f){
    if(f.path.endswith('.min.js')){
        return false;
    }
    return true;
};

gulp.task('jsmin', function (cb) {
        return gulp.src([SRC_DIR+'/**/*.js'])
        .pipe(sourcemaps.init())
        .pipe(gulpif(condition, uglify({mangle: {except: ['require' ,'exports' ,'module' ,'$']}}))) //消除殽杂关键字
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(DEST_DIR));

});

gulp-filter

API
filter(pattern, [options])
Returns a transform stream with a .restore object.
参数申明:
pattern
Type: string, array, function
Accepts a string/array with globbing patterns which are run through multimatch.
假如是函数,则应当接收一个 vinyl file object作为第一个参数,return true/false whether to include the file:

filter(file => /unicorns/.test(file.path));

选项options
Type: object
Accepts minimatch options.
Note: Set dot: true if you need to match files prefixed with a dot (eg. .gitignore).

options.restore
Type: boolean
Default: false
Restore filtered files.

options.passthrough
Type: boolean
Default: true

When set to true filtered files are restored with a PassThrough stream, otherwise, when set to false, filtered files are restored as a Readable stream.

官方例子:

const gulp = require('gulp');
const uglify = require('gulp-uglify');
const filter = require('gulp-filter');

gulp.task('default', () => {
    // create filter instance inside task function
    const f = filter(['**', '!*src/vendor'], {restore: true});

    return gulp.src('src/**/*.js')
        // filter a subset of the files
        .pipe(f)
        // run them through a plugin
        .pipe(uglify())
        // bring back the previously filtered out files (optional)
        .pipe(f.restore)
        .pipe(gulp.dest('dist'));
});
gulp.task('defaultmulti', () => {
    const jsFilter = filter('**/*.js', {restore: true});
    const lessFilter = filter('**/*.less', {restore: true});

    return gulp.src('assets/**')
        .pipe(jsFilter)
        .pipe(concat('bundle.js'))
        .pipe(jsFilter.restore)
        .pipe(lessFilter)
        .pipe(less())
        .pipe(lessFilter.restore)
        .pipe(gulp.dest('out/'));
});

实战:

var condition = function(f){
        if(f.path.endswith('.min.js')){
            return false;
        }
        return true;
    };
const jsFilter = filter(condition, {restore: true});
   
    gulp.task('jsmin', function (cb) {
            return gulp.src([SRC_DIR+'/**/*.js'])
            .pipe(jsFilter)
            .pipe(sourcemaps.init())
            .pipe(uglify({mangle: {except: ['require' ,'exports' ,'module' ,'$']}})) //消除殽杂关键字
            .pipe(sourcemaps.write('.'))
            .pipe(jsFilter.restore)
            .pipe(gulp.dest(DEST_DIR));
    
    });

部份文件被紧缩,一切文件都邑被发送到DEST_DIR

小结

怎样挑选?
gulp-if:能够圆满解决题目,且充足文雅。
gulp-filter:能够圆满解决题目,然则比拟gulp-if略显贫苦。更庞杂的场景下用gulp-filter比gulp-if轻易。
gulp-ignore:更加壮大的过滤,在仅仅只是过滤而不拷贝的状况下首推。

    原文作者:xbynet
    原文地址: https://segmentfault.com/a/1190000007771583
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞