roberto tomás roberto tomás - 2 months ago 11
Javascript Question

gulp intermittedly creating destination directories

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.

Answer

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

Comments