Gulp watch not triggering minify on file change - gulp

I have simple starter app, I created gulpfile.js file with content below,
let gulp = require('gulp');
let cleanCSS = require('gulp-clean-css');
// Task to minify css using package cleanCSs
gulp.task('minify-css', () => {
// Folder with files to minify
return gulp.src('src/assets/styles/*.css')
//The method pipe() allow you to chain multiple tasks together
//I execute the task to minify the files
.pipe(cleanCSS())
//I define the destination of the minified files with the method dest
.pipe(gulp.dest('src/assets/dist'));
});
//We create a 'default' task that will run when we run `gulp` in the project
gulp.task('default', function() {
// We use `gulp.watch` for Gulp to expect changes in the files to run again
gulp.watch('./src/assets/styles/*.css', function(evt) {
gulp.task('minify-css');
});
});
if I run gulp minify-css it works expected, but I need it to minify on file change
But all its do log a message in cmd windows like 'Starting ...'
I don't even know what does it mean...
package.json:
..
"gulp": "^4.0.2",
"gulp-clean-css": "^4.2.0"

I think you need to add return when running task minify-css, so that system knows when previous task was completed.
gulp.task('default', function() {
// We use `gulp.watch` for Gulp to expect changes in the files to run again
gulp.watch('./src/assets/styles/*.css', function(evt) {
return gulp.task('minify-css');
});
});

Related

Why subTasks not created in my task runner explorer?

I am working on my Gulp tutorial(using this site: http://www.davepaquette.com/archive/2014/10/08/how-to-use-gulp-in-visual-studio.aspx).
Here is gulpFile.js:
// include plug-ins
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var del = require('del');
var config = {
//Include all js files but exclude any min.js files
src: ['app/**/*.js', '!app/**/*.min.js']
}
//delete the output file(s)
gulp.task('clean', function () {
//del is an async function and not a gulp plugin (just standard nodejs)
//It returns a promise, so make sure you return that from this task function
// so gulp knows when the delete is complete
return del(['app/all.min.js']);
});
// Combine and minify all files from the app folder
// This tasks depends on the clean task which means gulp will ensure that the
// Clean task is completed before running the scripts task.
gulp.task('scripts', ['clean'], function () {
return gulp.src(config.src)
.pipe(uglify())
.pipe(concat('all.min.js'))
.pipe(gulp.dest('app/'));
});
gulp.task('watch', function () {
return gulp.watch(config.src, ['scripts']);
});
//Set a default tasks
gulp.task('default', ['scripts'], function () { });
Here is task runner explorer:
And here how task runner explorer looks in tutorial site above:
Any idea why I dont see subTasks in my task runner explorer?
This is the only way so far that I've been able to fix this.
After adding a task, rename your gulpfile to something else and then close Task Runner Explorer.
Change the renamed file back to gulpfile.js, then reopen Task Runner Explorer.
You should see your gulpfile tasks updated.

Gulp task executed by watch using cached config stream

I'm trying use gulp to bundle and minify my files using gulp-bundle-assets. Running the tasks on their own is fine. My problem is using gulp.watch to watch for any changes in my config file and re-bundle my scripts.
The first time the watch executes everything works correctly. On successive occasions everything runs, but the exact same files are bundled - any changes in the config are ignored.
If I run my "bundle" task while the watch is running, "bundle" will use the current configuration. While successive watches will continue to use the configuration on the first execution.
My guess would be the data for the stream retrieved by gulp.src is cached. So how do I tell it to always get the latest version?
var gulp = require('gulp');
var bundle = require('gulp-bundle-assets');
var del = require('del');
var index = 0;
gulp.task('bundle', function () {
console.log('Bundling files ' + (index++));
return gulp.src('./bundle.config.js')
.pipe(bundle())
.pipe(gulp.dest('./bundles'));
});
gulp.task('watch', function () {
gulp.watch(['./scripts/**/*.{js,css}', './bundle.config.js'], ['clean', 'bundle']);
});
gulp.task('clean', function (cb) {
console.log('Cleaning files');
del(['./bundles/**/*'], cb);
});
An alternative I tried was to use watch(...).on, and calling gulp.run, but that didn't fix the problem, either. I also tried pasting the code from the bundle task in to the on callback, but still got the same result.
The culprit isn't gulp.src(), but bundle(). The gulp-bundle-assets plugin uses require() to load your bundle.config.js. Since Node.js caches return values from require() you always get the same config object after the file is loaded for the first time.
The solution is to invalidate the require cache in your bundle task:
var gulp = require('gulp');
var bundle = require('gulp-bundle-assets');
var del = require('del');
var index = 0;
gulp.task('bundle', ['clean'], function () { // run clean task before bundle task
// invalidate require cache for ./bundle.config.js
delete require.cache[require.resolve('./bundle.config.js')];
console.log('Bundling files ' + (index++));
return gulp.src('./bundle.config.js')
.pipe(bundle())
.pipe(gulp.dest('./bundles'));
});
gulp.task('watch', function () {
gulp.watch(['./scripts/**/*.{js,css}',
'./bundle.config.js'], ['bundle']); // only run bundle task
});
gulp.task('clean', function () {
console.log('Cleaning files');
return del(['./bundles/**/*']); // return promise object
});
Unrelated to your problem, but I also fixed your clean task. The way you had it set up didn't work.

Gulp use changed-in-place with multiple tasks that depend on each other

I'm using the gulp-changed-in-place package to only run certain Gulp tasks with the files that have changed (https://github.com/alexgorbatchev/gulp-changed-in-place). I'm having an issue where I only want to run my linting and code style tasks on changed files to speed up development time.
My current setup is as follows:
var gulp = require('gulp');
var changedInPlace = require('gulp-changed-in-place');
var eslint = require('gulp-eslint');
var jscs = require('gulp-jscs');
var config = {
paths: {
js: './app/**/*.js'
}
}
gulp.task('jscs', function() {
return gulp.src(config.paths.js)
.pipe(changedInPlace())
.pipe(jscs())
.pipe(jscs.reporter())
.pipe(jscs.reporter('fail'));
});
gulp.task('lint', ['jscs'], function() {
return gulp.src(config.paths.js)
.pipe(changedInPlace())
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
gulp.task('js', ['lint'], function() {
// do some stuff
});
gulp.task('watch', function() {
gulp.watch(config.paths.js, ['js']);
});
The issue is probably pretty obvious. The js task has a dependency on the lint task which itself has a dependency on the jscs task - so the jscs task runs first. It accesses changedInPlace() which causes the cache to get updated and therefore the changedInPlace() call from the lint task doesn't think anything has changed and doesn't check the files I expect.
Has anyone used this package with this issue and do you have any suggestions on what to do? Also open to other ways of accomplishing the task - only running the js task on changed files.

Gulp, make a task use another tasks output

I'm building a workflow with Gulp for handling e-mails and I'm having some trouble.
My gulp file compiles a jade file into html, and I then want to run another task on the html file that this task outputs. I have set it up like shown in the code below.
The problem is that, even though the console says that the 'emailBuilder' task is run, it's not doing anything. But if I run 'emailBuilder' separately after 'gulp build' it does do what it should.
Image shows that emailBuilder is run last, still doesn't do what it should.
How can I make this work smoothly?
//-----------------------------------------------------
// ### REQUIREMENTS
//-------------------
var gulp = require('gulp'),
jade = require('gulp-jade'),
sass = require('gulp-sass'),
del = require('del'),
emailBuilder = require('gulp-email-builder'),
runSequence = require('gulp-run-sequence');
//-----------------------------------------------------
// ### Clean
// `gulp clean`
//-------------------
// Clean our compiled folder before we generate new content into it
gulp.task('clean', function (cb) {
del([
// here we use a globbing pattern to match everything inside the `compiled` folder, except our gitkeep file
'compiled/**/*',
], { dot: true },
cb);
});
//-----------------------------------------------------
// ### Compile SCSS
// `gulp compile-css`
//-------------------
gulp.task('compile-scss', function () {
gulp.src('./src/scss/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./compiled/css'));
});
//-----------------------------------------------------
// ### Build Jade templates
// `gulp templates`
//-------------------
gulp.task('templates', function() {
var YOUR_LOCALS = {};
gulp.src('./src/templates/*.jade')
.pipe(jade({
pretty: true,
locals: YOUR_LOCALS
}))
.pipe(gulp.dest('./compiled/templates/'));
});
//-----------------------------------------------------
// ### Inline CSS, send tests
// `gulp compile-css`
//-------------------
gulp.task('emailBuilder', function() {
return gulp.src(['./compiled/templates/*.html'])
.pipe(emailBuilder())
.pipe(gulp.dest('./compiled/templates/'));
});
//-----------------------------------------------------
// ### Build
// `gulp build` - Clean up the builds directory and do a complete build.
//-------------------
gulp.task('build', function(callback) {
runSequence(
'clean',
'compile-scss',
'templates',
'emailBuilder',
callback);
});
You need to add a return statement to your tasks. According to the gulp API docs on tasks:
Make sure your dependency tasks are correctly using the async run hints: take in a callback or return a promise or event stream.
If you don't return a promise or the event stream (or use a callback) the following tasks won't know when the previous one is done.
I suspect that in your case the emailBuilder task is run too soon.

gulp-assemble & gulp-watch not recompiling site when changes are made to data, includes or layouts

I'm having issues using gulp-assemble with gulp-watch. I want gulp to watch the entire assemble source directory (data, includes, layouts and pages) and recompile the site when ever a file changes.
I'm able to get this working correctly for pages, but gulp is not recompiling the site when changes are made to the data, includes or layouts files.
I've added a watch task to the example gulpfile.js in the gulp-assemble repository:
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var extname = require('gulp-extname');
var assemble = require('assemble');
var middleware = require('./examples/middleware');
var gulpAssemble = require('./');
// setup items on the assemble object
assemble.data({site: {title: 'Blog'}});
assemble.data(['test/fixtures/data/*.{json,yml}']);
assemble.layouts(['test/fixtures/layouts/*.hbs']);
assemble.partials(['test/fixtures/includes/*.hbs']);
// arbitrary middleware that runs when files loaded
assemble.onLoad(/index\.hbs/, middleware(assemble));
// render templates in `test/fixtures`
gulp.task('default', function () {
gulp.src('test/fixtures/pages/*.hbs')
.pipe(gulpAssemble(assemble, { layout: 'default' }))
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(extname())
.pipe(gulp.dest('_gh_pages/'));
});
// ============================================================
// my watch task
// ============================================================
gulp.task('watch', ['default'], function() {
gulp.watch('test/fixtures/**/*.{hbs,yml,json}', ['default']);
});
If I run gulp watch and save a change to any of the .hbs files in the pages directory, I see gulp trigger the default in my terminal output, and I see the .html file in _gh_pages update with the change.
However, if I save a change to any of the .hbs, .json, or .yml files in the data, includes or layouts directories, I see gulp trigger the default in my terminal output, but I see no changes to the _gh_pages .html file(s). I have to run the gulp default task manually in order to get the changes applied to the _gh_pages files.
What do I need to change in order to get the desired behaviour?
gulp-watch will only execute code inside the function for the default task, so to get things like data and layouts to reload, you'll need to move those pieces of code to inside the function (Just before gulp.src).
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var extname = require('gulp-extname');
var assemble = require('assemble');
var middleware = require('./examples/middleware');
var gulpAssemble = require('./');
// arbitrary middleware that runs when files loaded
assemble.onLoad(/index\.hbs/, middleware(assemble));
// render templates in `test/fixtures`
gulp.task('default', function () {
// setup items on the assemble object
assemble.data({site: {title: 'Blog'}});
assemble.data(['test/fixtures/data/*.{json,yml}']);
assemble.layouts(['test/fixtures/layouts/*.hbs']);
assemble.partials(['test/fixtures/includes/*.hbs']);
gulp.src('test/fixtures/pages/*.hbs')
.pipe(gulpAssemble(assemble, { layout: 'default' }))
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(extname())
.pipe(gulp.dest('_gh_pages/'));
});
// ============================================================
// my watch task
// ============================================================
gulp.task('watch', ['default'], function() {
gulp.watch('test/fixtures/**/*.{hbs,yml,json}', ['default']);
});