Gulp, make a task use another tasks output - gulp

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.

Related

Gulp watch not triggering minify on file change

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');
});
});

gulp task throwing error on second time run

I have two folders both of which contain some html template files. I need to minify these files to separate folders.
folder structure
|src
|--clientTemplates
|----abc.html
|----xyz.html
|--serverTemplates
|----abc.html
|----xyz.html
required destination folder
|dist
|--client
|----abc.html
|----xyz.html
|--server
|----abc.html
|----xyz.html
following is my gulpfile where I have my tasks defined for the
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var replace = require('gulp-replace');
var del = require('del');
var minOptions = {
collapseWhitespace: true,
minifyJS: { output: { quote_style: 1 } },
minifyCSS: true
};
gulp.task('clean', function(done) {
del(['dist'], done());
});
gulp.task('minify:serverTemplates', function() {
return gulp
.src('src/serverTemplates/*.html')
.pipe(htmlmin(minOptions))
.pipe(replace('\\', '\\\\'))
.pipe(replace('"', '\\"'))
.pipe(gulp.dest('dist/server'));
});
gulp.task('minify:clientTemplates', function() {
return gulp
.src('src/clientTemplates/*.html')
.pipe(htmlmin(minOptions))
.pipe(gulp.dest('dist/client'));
});
gulp.task(
'default',
gulp.series('clean', 'minify:serverTemplates', 'minify:clientTemplates', function inSeries(done) {
done();
})
);
when I run the gulp command it works fine for the first time, but throws errors on alternate runs.
running gulp command first time
running gulp command second time
can't figure out what exactly is wrong there.
Also is there a way to run the two minification task parallel once the clean task has finished?
thanks for the help.
The callback you pass to del is wrong. Just return the promise:
gulp.task('clean', function() {
return del(['dist']);
});
As for running the minification tasks in parallel, use gulp.parallel:
gulp.task(
'default',
gulp.series(
'clean',
gulp.parallel('minify:serverTemplates', 'minify:clientTemplates')
)
);

execute tasks synchronously in gulp

I have read online that 'run-sequence' will make sure all specified tasks will run synchronously. For some reason this is not true in my case. Am I missing something?
'convertSassToCss' is the task that does not work as intended
If I would run tasks 'cleanAllCss' and 'convertSassToCss' seperatelly, it would work.
The idea here is to first remove all css files from directory, then convert all sass files into css and place the into the cleaned dir
/// <binding BeforeBuild='clean, min:css' Clean='clean' />
"use strict";
var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify"),
sass = require('gulp-sass'),
rename = require('gulp-rename'),
del = require('del'),
runSequence = require('run-sequence');
var paths = {
webroot: "./wwwroot/"
};
paths.cssPath = paths.webroot + "css/*.css";
paths.cssOutputPath = paths.webroot + "css";
//sass
paths.sassPath = paths.webroot + "sass/**/*.scss";
paths.sassOutputPath = paths.webroot + "./css/file";
gulp.task("cleanAllCss", function (cb) {
console.log("2 -- Removing all CSS files");
del([paths.cssOutputPath + "/*.css"], cb);
console.log("2 -- DONE - Removed all css files");
});
gulp.task("convertSassToCss", function (cb) {
console.log("3 -- Converting all SASS files into corresponding CSS");
gulp.src(paths.sassPath)
.pipe(sass())
.pipe(gulp.dest(paths.cssOutputPath));
console.log("3 -- DONE - Converting all SASS files into corresponding CSS");
});
//not working, should run in sequence
gulp.task("convertAllSassIntoCssMin", function (callback) {
console.log("1 -- Converting all SASS files into corresponding min CSS files")
runSequence('cleanAllCss', 'convertSassToCss', callback);
console.log("1 -- DONE - Converting all SASS files into corresponding min CSS files")
});
I cannot speak to run-sequence as I haven't used it before.
However, you can run tasks in sequence by using Gulp's task dependency feature, where a task will NOT run until it's dependencies have finished running.
Your new tasks signatures
cleanAllCss stays the same:
gulp.task("cleanAllCss", function (cb) { ... }
convertSassToCss changes to:
gulp.task("convertSassToCss", ['cleanAllCss'], function (cb) { ... }
convertAllSassIntoCssMin changes to:
gulp.task("convertAllSassIntoCssMin", ['convertSassToCss'], function (cb) { ... }
This ensures that convertAllSassIntoCssMin won't run until convertSassToCss has finished which in turn won't run until cleanAllCss has finished.
Refer to gulp deps:
deps
Type: Array
An array of tasks to be executed and completed before your task will
run.
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
// Do stuff }); Note: Are your tasks running before the dependencies
are complete? Make sure your dependency tasks are correctly using the
async run hints: take in a callback or return a promise or event
stream.
You can also omit the function if you only want to run a bundle of
dependency tasks:
gulp.task('build', ['array', 'of', 'task', 'names']); Note: The tasks
will run in parallel (all at once), so don't assume that the tasks
will start/finish in order.
The problem is in the cleanAllCss task. The second parameter accepted by del is options, not the callback which you're trying to pass. The callback is never executed. Try running it manually when the removal is finished.
gulp.task("cleanAllCss", function (cb) {
console.log("2 -- Removing all CSS files");
del([paths.cssOutputPath + "/*.css"]).then(paths => {
console.log("2 -- DONE - Removed all css files");
cb();
};
});

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 - SCSS Lint - Don't compile SCSS if linting fails

Just wondering if someone can help me with my Gulp setup. At the moment I am using gulp-sass and gulp-scss-lint with a watch task. What I want to happen is that when an scss file is saved for the linting task to run completely and if any errors or warnings are thrown up for the scss files not to compile and for watch to continue running.
At the moment I seem to have this working with errors but not with the warnings, which still compile the stylesheets.
/// <binding ProjectOpened='serve' />
// Macmillan Volunteering Village Gulp file.
// This is used to automate the minification
// of stylesheets and javascript files. Run using either
// 'gulp', 'gulp watch' or 'gulp serve' from a command line terminal.
//
// Contents
// --------
// 1. Includes and Requirements
// 2. SASS Automation
// 3. Live Serve
// 4. Watch Tasks
// 5. Build Task
'use strict';
//
// 1. Includes and Requirements
// ----------------------------
// Set the plugin requirements
// for Gulp to function correctly.
var gulp = require('gulp'),
notify = require("gulp-notify"),
sass = require('gulp-sass'),
scssLint = require('gulp-scss-lint'),
gls = require('gulp-live-server'),
// Set the default folder structure
// variables
styleSheets = 'Stylesheets/',
styleSheetsDist = 'Content/css/',
html = 'FrontEnd/';
//
// 2. SASS Automation
// ------------------
// Includes the minification of SASS
// stylesheets. Output will be compressed.
gulp.task('sass', ['scss-lint'], function () {
gulp.src(styleSheets + 'styles.scss')
.pipe(sass({
outputStyle: 'compressed'
}))
.on("error", notify.onError(function (error) {
return error.message;
}))
.pipe(gulp.dest(styleSheetsDist))
.pipe(notify({ message: "Stylesheets Compiled", title: "Stylesheets" }))
});
// SCSS Linting. Ignores the reset file
gulp.task('scss-lint', function () {
gulp.src([styleSheets + '**/*.scss', '!' + styleSheets + '**/_reset.scss'])
.pipe(scssLint({
'endless': true
}))
.on("error", notify.onError(function (error) {
return error.message;
}))
});
//
// 3. Live Serve
// -------------
gulp.task('server', function () {
var server = gls.static('/');
server.start();
// Browser Refresh
gulp.watch([styleSheets + '**/*.scss', html + '**/*.html'], function () {
server.notify.apply(server, arguments);
});
});
// Task to start the server, followed by watch
gulp.task('serve', ['default', 'server', 'watch']);
//
// 4. Watch Tasks
// --------------
gulp.task('watch', function () {
// Stylesheets Watch
gulp.watch(styleSheets + '**/*.scss', ['scss-lint', 'sass']);
});
//
// 5. Build Task
// --------------
gulp.task('default', ['sass']);
Seems that #juanfran has answered this question on GitHub in 2015. I will just repost it here.
1) Using gulp-if you can add any condition you like.
var sass = require('gulp-sass');
var gulpif = require('gulp-if');
var scssLint = require('gulp-scss-lint')
gulp.task('lint', function() {
var condition = function(file) {
return !(file.scssLint.errors || file.scssLint.warnings);
};
return gulp.src('**/*.scss')
.pipe(scssLint())
.pipe(gulpif(condition, sass()));
});
2) Another more specific option is to use Fail reporter that will fail in case of any errors or warnings
gulp.task('scss-lint', function() {
return gulp.src('**/*.scss')
.pipe(scssLint())
.pipe(scssLint.failReporter());
});
gulp.task('sass', ['scss-lint'], function() {
return gulp.src('**/*.scss')
.pipe(scss());
});