248

I have a gulp rjs task that concatenates and uglifies all my custom .JS files (any non vendor libraries).

What i am trying to do, is exclude some files/directories from this task (controllers and directives).

Heres my tree:

 - application
    - resources
      - js
        main.js
        - vendor
            - jquery
            - modernzr
            - angular
        - controllers
            - controller1
            - controller2
            - controller3
        - directives
            - directives1
            - directives2
            - directives3
        - widgets
            - widget1
            - widget2
            - widget3
            - widget4
        - modules
            - modules1
            - modules2
            - modules3
            - modules4

Here my gulp.js

dir = {
    app:        'application',
    dest:       'dest',
};

config = {
    src: {
        js: dir.app + '/resources/js'
    },
    dest: {
        js: dir.dest + '/resources/js'
    }
};

gulp.task('rjs', function() {

      rjs({
            baseUrl: config.src.js,
            out: 'main.js',
            name: 'main',
            mainConfigFile: config.src.js + '/main.js',
            exclude: [ 'jquery', 'angular']         
        })
        .pipe(prod ? uglify({ mangle: false, outSourceMap: true, compress: { drop_console: true } }) : gutil.noop())
        .pipe(gulp.dest(config.dest.js))
        .pipe(filesize())
        .pipe(dev ? connect.reload() : gutil.noop());

});
Anshul
  • 9,312
  • 11
  • 57
  • 74
Oam Psy
  • 8,555
  • 32
  • 93
  • 157
  • 1
    Have you tried gulp-ignore? https://www.npmjs.org/package/gulp-ignore – danbars Jul 01 '14 at 06:14
  • 1
    @user1655734 : the gulp-ignore documentation (https://www.npmjs.com/package/gulp-ignore) suggests the exclude pattern (`gulp.src(['./*.js', '!./node_modules/**'])`) first, then gulp-ignore – Jeromy French Aug 26 '15 at 14:12

2 Answers2

572

Quick answer

On src, you can always specify files to ignore using "!".

Example (you want to exclude all *.min.js files on your js folder and subfolder:

gulp.src(['js/**/*.js', '!js/**/*.min.js'])

You can do it as well for individual files.

Expanded answer:

Extracted from gulp documentation:

gulp.src(globs[, options])

Emits files matching provided glob or an array of globs. Returns a stream of Vinyl files that can be piped to plugins.

glob refers to node-glob syntax or it can be a direct file path.

So, looking to node-glob documentation we can see that it uses the minimatch library to do its matching.

On minimatch documentation, they point out the following:

if the pattern starts with a ! character, then it is negated.

And that is why using ! symbol will exclude files / directories from a gulp task

Community
  • 1
  • 1
avcajaraville
  • 9,041
  • 2
  • 28
  • 37
  • 11
    Shouldn't this be avoided? This is from the node-glob documentation: `Negation The intent for negation would be for a pattern starting with ! to match everything that doesn't match the supplied pattern. However, the implementation is weird, and for the time being, this should be avoided. The behavior is deprecated in version 5, and will be removed entirely in version 6.` – Mister Oh Mar 11 '15 at 18:47
  • 2
    I needed to use: `gulp.src([/*file globs*/], {base:"."})` in order to get the glob patterns to work correctly. – Scott Jun 24 '15 at 05:07
  • @Scott: yeah, but that have nothing to do with this answer/question. – avcajaraville Jun 24 '15 at 08:47
  • @MisterOh: thats what the documentation says. I did research trying to find the right way, but no idea yet. I opened an issue (https://github.com/isaacs/node-glob/issues/201) and still waiting for an answer. As soon as we know the preferred way, I will update my answer. In the meantime, I think this answer is still valid. – avcajaraville Jun 24 '15 at 08:48
  • 2
    @avcajaraville I agree that your answer is totally valid. I was not able to get the posted response working correctly without what I responded in my comment. Not sure how that has nothing to do with the answer/question, but just wanted to post what worked for me. – Scott Jun 24 '15 at 14:15
  • 1
    @MisterOh actually, gulp.src is vinyl-fs.src, which passes the globbing off to glob-stream, which in turn uses [node-glob](https://github.com/isaacs/node-glob) for the positive globs and [minimatch](https://github.com/isaacs/minimatch) for the negative globs, so it's ok to use negative patterns. Check out the [glob-stream documentation and sample positive and negative glob patterns here](https://github.com/wearefractal/glob-stream), or [have a look at the code](https://github.com/wearefractal/glob-stream/blob/799c843870735021613b37fb486b7545a6cb3ea0/index.js#L91). – Codebling Jul 12 '15 at 04:09
  • 20
    Negation is the right way to do this. The gulp documentation was incorrect. I opened an [issue](https://github.com/gulpjs/gulp/issues/1296) regarding the docs and submitted [PR](https://github.com/gulpjs/gulp/pull/1299) that has [corrected documentation](https://github.com/breyed/gulp/blob/patch-1/docs/API.md). – Edward Brey Oct 01 '15 at 14:57
  • @EdwardBrey Amazing job ! Thanks so much, this really helps on clarify ! – avcajaraville Oct 02 '15 at 14:58
  • i just get this error 'Error: Missing positive glob'. Code gulp.src([globs.images] , {base:"."}). globs.images works fine when not in[globs.images]. – v3nt Jun 15 '18 at 11:43
  • 1
    @v3nt, my guess is your glob.images is already and array, so no need for brackets there. ;) – avcajaraville Jun 18 '18 at 08:38
15

Gulp uses micromatch under the hood for matching globs, so if you want to exclude any of the .min.js files, you can achieve the same by using an extended globbing feature like this:

src("'js/**/!(*.min).js")

Basically what it says is: grab everything at any level inside of js that doesn't end with *.min.js

Jair Reina
  • 2,606
  • 24
  • 19