0

Why does gulp only sometimes create the subdirectory, even when there are no changes to the source files/directories and I am just rerunning gulp?

Sometimes my gulpfile works just fine.. like after running it the first time after creating the build directory:

PS C:\Users\RobertoTomás\OneDrive\Público\projects\Overwatch> gulp
[09:56:11] Requiring external module babel-register
[09:56:13] Using gulpfile ~\OneDrive\Público\projects\Overwatch\gulpfile.babel.js
[09:56:13] Starting 'default'...
[09:56:13] Starting 'clean'...
[09:56:13] Starting 'root'...
[09:56:13] Finished 'root' after 6.23 ms
[09:56:13] Starting 'templates'...
[09:56:13] Finished 'templates' after 1.68 ms
[09:56:13] Starting 'css'...
[09:56:13] Finished 'css' after 7.43 ms
[09:56:13] Starting 'sass'...
[09:56:13] Finished 'sass' after 6.96 ms
[09:56:13] Starting 'scripts'...
[09:56:13] Finished 'scripts' after 3.88 ms
[09:56:13] Finished 'default' after 39 ms
[09:56:13] Finished 'clean' after 91 ms
[09:56:14] File dev\styles\bootstrap-theme.css found.
[09:56:14] Processed media queries:
[09:56:14]   @media (max-width: 767px)
[09:56:14] File dev\styles\bootstrap-theme.css created.
[09:56:14] File dev\styles\bootstrap-theme.min.css found.
[09:56:14] Processed media queries:
[09:56:14]   @media (max-width:767px)
[09:56:14] File dev\styles\bootstrap-theme.min.css created.
[09:56:15] File dev\styles\bootstrap.css found.
[09:56:15] Processed media queries:
[09:56:15]   @media screen and (-webkit-min-device-pixel-ratio: 0)
[09:56:15]   @media (max-device-width: 480px) and (orientation: landscape)
[09:56:15]   @media all and (transform-3d), (-webkit-transform-3d)
[09:56:15]   @media (min-width: 768px)
[09:56:15]   @media screen and (min-width: 768px)
[09:56:15]   @media (min-width: 768px) and (max-width: 991px)
[09:56:15]   @media (min-width: 992px)
[09:56:15]   @media (min-width: 992px) and (max-width: 1199px)
[09:56:15]   @media (min-width: 1200px)
[09:56:15]   @media screen and (max-width: 767px)
[09:56:15]   @media (max-width: 767px)
[09:56:15]   @media print
[09:56:15] File dev\styles\bootstrap.css created.
[09:56:15] File dev\styles\bootstrap.min.css found.
[09:56:15] Processed media queries:
[09:56:15]   @media screen and (-webkit-min-device-pixel-ratio:0)
[09:56:15]   @media (max-device-width:480px) and (orientation:landscape)
[09:56:15]   @media all and (transform-3d),(-webkit-transform-3d)
[09:56:15]   @media (min-width:768px)
[09:56:15]   @media screen and (min-width:768px)
[09:56:15]   @media (min-width:768px) and (max-width:991px)
[09:56:15]   @media (min-width:992px)
[09:56:15]   @media (min-width:992px) and (max-width:1199px)
[09:56:15]   @media (min-width:1200px)
[09:56:15]   @media screen and (max-width:767px)
[09:56:15]   @media (max-width:767px)
[09:56:15]   @media print
[09:56:15] File dev\styles\bootstrap.min.css created.
[09:56:16] File dev\styles\main.css found.
[09:56:16] File dev\styles\main.css created.
[BS] Access URLs:
 ------------------------------------
       Local: http://localhost:3000
    External: http://192.168.1.9:3000
 ------------------------------------
          UI: http://localhost:3001
 UI External: http://192.168.1.9:3001
 ------------------------------------
[BS] Serving files from: ./build/
[BS] 5 files changed (bootstrap-theme.min.css, bootstrap-theme.min.min.css, bootstrap.min.css, bootstrap.min.min.css, ma
in.min.css)
[BS] 7 files changed (404.html, index.html, browserconfig.xml, apple-touch-icon.png, tile-wide.png, tile.png, favicon.ic
o)
[BS] 5 files changed (bootstrap.min.js, bootstrap.min.min.js, jquery-3.1.0.min.js, main.min.js, modernizr-2.8.3-respond-
1.4.2.min.min.js)

But most of the time (but not always), I gett an error with the styles subdirectory:

PS C:\Users\RobertoTomás\OneDrive\Público\projects\Overwatch> gulp
[09:57:31] Requiring external module babel-register
[09:57:33] Using gulpfile ~\OneDrive\Público\projects\Overwatch\gulpfile.babel.js
[09:57:33] Starting 'default'...
[09:57:33] Starting 'clean'...
[09:57:33] Starting 'root'...
[09:57:33] Finished 'root' after 6.26 ms
[09:57:33] Starting 'templates'...
[09:57:33] Finished 'templates' after 1.77 ms
[09:57:33] Starting 'css'...
[09:57:33] Finished 'css' after 7.78 ms
[09:57:33] Starting 'sass'...
[09:57:33] Finished 'sass' after 6.5 ms
[09:57:33] Starting 'scripts'...
[09:57:33] Finished 'scripts' after 3.82 ms
[09:57:33] Finished 'default' after 39 ms
[09:57:34] File dev\styles\bootstrap-theme.css found.
[09:57:34] Processed media queries:
[09:57:34]   @media (max-width: 767px)
[09:57:34] File dev\styles\bootstrap-theme.css created.
[09:57:34] File dev\styles\bootstrap-theme.min.css found.
[09:57:34] Processed media queries:
[09:57:34]   @media (max-width:767px)
[09:57:34] File dev\styles\bootstrap-theme.min.css created.
[09:57:35] File dev\styles\bootstrap.css found.
[09:57:35] Processed media queries:
[09:57:35]   @media screen and (-webkit-min-device-pixel-ratio: 0)
[09:57:35]   @media (max-device-width: 480px) and (orientation: landscape)
[09:57:35]   @media all and (transform-3d), (-webkit-transform-3d)
[09:57:35]   @media (min-width: 768px)
[09:57:35]   @media screen and (min-width: 768px)
[09:57:35]   @media (min-width: 768px) and (max-width: 991px)
[09:57:35]   @media (min-width: 992px)
[09:57:35]   @media (min-width: 992px) and (max-width: 1199px)
[09:57:35]   @media (min-width: 1200px)
[09:57:35]   @media screen and (max-width: 767px)
[09:57:35]   @media (max-width: 767px)
[09:57:35]   @media print
[09:57:35] File dev\styles\bootstrap.css created.
[09:57:36] File dev\styles\bootstrap.min.css found.
[09:57:36] Processed media queries:
[09:57:36]   @media screen and (-webkit-min-device-pixel-ratio:0)
[09:57:36]   @media (max-device-width:480px) and (orientation:landscape)
[09:57:36]   @media all and (transform-3d),(-webkit-transform-3d)
[09:57:36]   @media (min-width:768px)
[09:57:36]   @media screen and (min-width:768px)
[09:57:36]   @media (min-width:768px) and (max-width:991px)
[09:57:36]   @media (min-width:992px)
[09:57:36]   @media (min-width:992px) and (max-width:1199px)
[09:57:36]   @media (min-width:1200px)
[09:57:36]   @media screen and (max-width:767px)
[09:57:36]   @media (max-width:767px)
[09:57:36]   @media print
[09:57:36] File dev\styles\bootstrap.min.css created.
[09:57:36] File dev\styles\main.css found.
[09:57:36] File dev\styles\main.css created.
[09:57:36] Plumber found unhandled error:
 Error: ENOENT: no such file or directory, chmod 'C:\Users\RobertoTomás\OneDrive\Público\projects\Overwatch\build\styles
\bootstrap-theme.min.css'
[09:57:36] Plumber found unhandled error:
 Error: ENOENT: no such file or directory, chmod 'C:\Users\RobertoTomás\OneDrive\Público\projects\Overwatch\build\styles
\bootstrap-theme.min.css'
[09:57:36] Finished 'clean' after 2.94 s
[BS] Access URLs:
 ------------------------------------
       Local: http://localhost:3000
    External: http://192.168.1.9:3000
 ------------------------------------
          UI: http://localhost:3001
 UI External: http://192.168.1.9:3001
 ------------------------------------
[BS] Serving files from: ./build/
[BS] 7 files changed (404.html, index.html, browserconfig.xml, apple-touch-icon.png, tile-wide.png, tile.png, favicon.ic
o)
[BS] 5 files changed (bootstrap.min.js, bootstrap.min.min.js, jquery-3.1.0.min.js, main.min.js, modernizr-2.8.3-respond-
1.4.2.min.min.js)

The whole styles subdirectory doesn't get created in build.

Here's my gulpfile:

var gulp = require('gulp');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var sourcemaps = require('gulp-sourcemaps');
var sass = require('gulp-sass');
var autoPrefixer = require('gulp-autoprefixer');
//if node version is lower than v.0.1.2
//require('es6-promise').polyfill();
var cssComb = require('gulp-csscomb');
var cmq = require('gulp-merge-media-queries');
var cleanCss = require('gulp-clean-css');
var browserify = require('gulp-browserify');
var uglify = require('gulp-uglify');

var browserSync = require('browser-sync').create();
var reload = browserSync.reload

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

gulp.task('clean', function (done) {
    gulp.src('build/*', { read: false })
        .pipe(clean())
    done()
})

gulp.task('sass', function (done) {
    gulp.src(['dev/styles/**/*.scss', 'dev/styles/**/*.sass'])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(sourcemaps.init())
        .pipe(sass())
        .pipe(autoPrefixer())
        .pipe(cssComb())
        .pipe(cmq({ log: true }))
        .pipe(gulp.dest('build/styles'))
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(cleanCss())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('build/styles'))
        .pipe(reload({ stream: true }))
    done()
});
gulp.task('css', function (done) {
    gulp.src(['dev/styles/**/*.css'])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(autoPrefixer())
        .pipe(cssComb())
        .pipe(cmq({ log: true }))
        .pipe(gulp.dest('build/styles'))
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(cleanCss())
        .pipe(gulp.dest('build/styles'))
        .pipe(reload({ stream: true }))
    done()
});
gulp.task('scripts', function (done) {
    gulp.src(['dev/scripts/**/*.js'])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(browserify())
        .pipe(gulp.dest('build/scripts'))
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(uglify())
        .pipe(gulp.dest('build/scripts'))
        .pipe(reload({ stream: true }))
    done()
});
gulp.task('templates', function (done) {
    gulp.src(['dev/hypermedia/**/*.html'])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(gulp.dest('build/hypermedia/'))
        .pipe(reload({ stream: true }))
    done()
});
gulp.task('root', function (done) {
    gulp.src(['dev/**/*.html', 'dev/**/*.xml', 'dev/**/*.png', 'dev/**/*.ico'])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(gulp.dest('build/'))
        .pipe(reload({ stream: true }))
    done()
});

gulp.task('all', function (done) {
    gulp.start('root', 'templates', 'css', 'sass', 'scripts')
    done()
})

gulp.task('default', ['clean', 'root', 'templates', 'css', 'sass', 'scripts'], function (done) {
    gulp.watch('dev/scripts/**/*.js', ['scripts']);
    gulp.watch('dev/styles/**/*.css', ['css']);
    gulp.watch(['dev/styles/**/*.scss', 'dev/styles/**/*.sass'], ['sass']);
    gulp.watch('hypermedia/**/*.html', ['templates']);
    gulp.watch(['dev/**/*.html', 'dev/**/*.xml', 'dev/**/*.png', 'dev/**/*.ico'], ['root']);
    browserSync.init({ server: './build/' });
    done()
});

This is particurally weird because, I only delete the style directory at the beginning (the dependancy, actually) of the default task..and I immediately recreate it (still in dependency. It should still be there.

I also tried implementing this with a promise, or as a series of .on('end' calls, with and without the done() callbacks, but I didn't find a solution in those either.

bonus question:

how can I match .min.js separately from .js so I am not processing 3rdparty js files? I'd be happy to use a vendor subdirectory, but then Im not sure how to include all subdirectories for processing except vendor.

roberto tomás
  • 4,435
  • 5
  • 42
  • 71

2 Answers2

2

1. You're not returning your streams.

You need to do this in every task:

gulp.task('sass',function(){
   return gulp.src(['dev/styles/**/*.scss','dev/styles/**/*.sass'])

You also need to remove all the pointless done() callbacks you have strewn around in your code.

Further reading: Async task support, Does a gulp task have to return anything?

2. You're running all your tasks in parallel.

gulp.task('default', ['clean', 'root', 'templates', 'css', 'sass', 'scripts'], function (done) {

The above doesn't run clean, root, templates, css, sass and scripts in order. It runs them all at the same time. That's why you get that ENOENT error. You're deleting files in your clean task while the other tasks are creating them.

The best approach in your case would probably be to use run-sequence:

var runSequence = require('run-sequence');

gulp.task('watch', function() {
  gulp.watch('dev/scripts/**/*.js', ['scripts']);
  gulp.watch('dev/styles/**/*.css', ['css']);
  gulp.watch(['dev/styles/**/*.scss', 'dev/styles/**/*.sass'], ['sass']);
  gulp.watch('hypermedia/**/*.html', ['templates']);
  gulp.watch(['dev/**/*.html', 'dev/**/*.xml', 'dev/**/*.png', 'dev/**/*.ico'], ['root']);
});

gulp.task('serve', function() {
  browserSync.init({ server: './build/' });
});

gulp.task('default', function(done) {
  runSequence('clean', ['root', 'templates', 'css', 'sass', 'scripts'], 'watch', 'serve', done);
});

The above ensures the following task order:

  1. clean
  2. root, templates, css, sass, scripts in parallel
  3. watch
  4. serve

Further reading: How to run Gulp tasks sequentially one after the other

Community
  • 1
  • 1
Sven Schoenung
  • 30,224
  • 8
  • 65
  • 70
  • thank you! I'm still a little unseure about when the callback is required vs not .. you use it yourself in the defult task for some reason — in any case, implementing your suggestions resolved my problem precisely. thank you. – roberto tomás Sep 17 '16 at 17:22
1

For the bonus question: you can exclude a file or pattern by giving it the ! prefix. If your js files (both minified and not) were in the top level of src, you'd use ['src/*.js','!src/*.min.js'].

See also the Glob Primer.

henry
  • 4,244
  • 2
  • 26
  • 37