Running Gulp task one after another in specific order - javascript

I need to run one gulp task that contains 3 or 4 another tasks. The problem is (steps):
In task #1 I need download file from remote server
After download completed, I need to run task #2
And when task #2 is done I need to run task #3
This is my code:
var gulp = require('gulp'),
decompress = require('gulp-decompress'),
download = require("gulp-download"),
ftp = require('gulp-ftp'),
gutil = require('gulp-util');
gulp.task('default', function(){
console.log("Hello gulp");
});
var src_download = [
"https://wordpress.org/latest.zip"
];
gulp.task('download', function(){
download(src_download)
.pipe(gulp.dest("./"));
});
gulp.task('unzip-wp', function(){
return gulp.src('latest.zip')
.pipe(decompress({strip: 1}))
.pipe(gulp.dest('./'));
});
gulp.task('install', ['download', 'unzip-wp']);
As you can see, when I am trying to run 'install' task - it will run 'unzip-wp' before 'download' has been completed...
What am I doing wrong?
I need to run 'unzip-wp' task only after 'download' task has been completed.
Thanks

You should have the 'unzip-wp' task wait for the 'download' task to finish. To make sure the 'download' task is really finished also add a return statement to that task, i.e. this would do what you're looking for:
var gulp = require('gulp'),
decompress = require('gulp-decompress'),
download = require("gulp-download"),
ftp = require('gulp-ftp'),
gutil = require('gulp-util');
gulp.task('default', function () {
console.log("Hello gulp");
});
var src_download = [
"https://wordpress.org/latest.zip"
];
gulp.task('download', function () {
return download(src_download)
.pipe(gulp.dest("./"));
});
gulp.task('unzip-wp', ['download'], function () {
return gulp.src('latest.zip')
.pipe(decompress({strip: 1}))
.pipe(gulp.dest('./'));
});
gulp.task('install', ['unzip-wp']);

Very simple there is no need of unzip task it will also unzip into wordpress folder for the sake that it will not mess your other files.
gulp.task('download', function(){
download(src_download)
.pipe(decompress({strip: 1}))
.pipe(gulp.dest('./wordpress'));
});
gulp.task('default', ['download']);

Related

Gulp task is running in infinite loop

I have a gulp task to copy all html files from source to destination.
html gulp task
var gulp = require('gulp');
module.exports = function() {
return gulp.src('./client2/angularts/**/*.html')
.pipe(gulp.dest('./client2/script/src/'));
};
and gulp watch which start running whenever I change .Html file it swill start html gulp task.
watch.ts
var gulp = require('gulp');
var watch = require('gulp-watch');
var sq = require('run-sequence');
module.exports = function () {
var tsClientHtml = [
'client2/**/*.html'
];
watch(tsClientHtml, function () {
gulp.run('html');
});
};
Its going in infinite loop, means whenever I am changing in html file its ruining html gulp task again and again...
Can someone please suggest what is wrong in this watch.ts
You are watching the dest folder. Try changing tsClientHtml to './client2/angularts/**/*.html'.

How to add a watch to a folder in gulp

I have the following glupfile.js, it works fine but I need to run the default gulp task when a files in folder.
How to change my script in order to support gulp watch?
var gulp = require('gulp');
var jscs = require('gulp-jscs');
var jshint = require('gulp-jshint');
var noop = function () { };
var stylish = require('gulp-jscs-stylish');
var folders = [
'./a/**/*.js',
'./b/**/*.js',
'./c/**/*.js',
'a.js',
'b.js',
'c.js',
'd.js'
];
gulp.task('default', function () {
gulp.src(folders)
.pipe(jshint()) // hint (optional)
.pipe(jscs()) // enforce style guide
.on('error', noop) // don't stop on error
.pipe(stylish.combineWithHintResults()) // combine with jshint results
.pipe(jshint.reporter('jshint-stylish')); // use any jshint reporter to log hint and style guide errors
});
Try adding a gulp task as given below
gulp.task('watch',function(){
gulp.watch(folders,['default']);
});
gulp.task('default',['watch']);
Basically it watches the folders for any change and if any change happens, it executes your default task.

Changing files in place with gulp

I have a gulp task that looks like this:
gulp.task('htmlServer', ['bower'], function(cb) {
return gulp.src(config.build.htmlServerFiles, {base: './'})
.pipe(gulp.dest(config.build.build));
});
It just moves some files around. The bower task makes some changes to these files in place.
gulp.task('bower', ['jadeServer'], function() {
gulp.src(path.join(config.build.basepath, 'public/index.html'))
.pipe(wiredep({
directory: path.join(config.build.basepath, 'public/bower_components/'),
bowerJson: require(path.join(config.build.basepath, './bower.json'))
}))
.pipe(gulp.dest(path.join(config.build.basepath, 'public')));
});
Unfortunately, the htmlServer task seems to move a version of the files that existed prior to the changes made by the bower task.
What am I doing wrong? Can I not change files in place?
Your 'bower' task must return its built pipe, otherwise it cannot signal when it's done and so the tasks are run in parallel.
See second example in https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md
var gulp = require('gulp');
var del = require('del'); // rm -rf
gulp.task('clean', function() {
return del(['output']);
});
gulp.task('templates', ['clean'], function() {
var stream = gulp.src(['src/templates/*.hbs'])
// do some concatenation, minification, etc.
.pipe(gulp.dest('output/templates/'));
return stream; // return the stream as the completion hint
});

Iterating over directories with Gulp?

I'm new to gulp, but I'm wondering if its possible to iterate through directories in a gulp task.
Here's what I mean, I know a lot of the tutorials / demos show processing a bunch of JavaScript files using something like "**/*.js" and then they compile it into a single JavaScript file. But I want to iterate over a set of directories, and compile each directory into it's own JS file.
For instance, I have a file structure like:
/js/feature1/something.js
/js/feature1/else.js
/js/feature1/foo/bar.js
/js/feature1/foo/bar2.js
/js/feature2/another-thing.js
/js/feature2/yet-again.js
...And I want two files: /js/feature1/feature1.min.js and /js/feature2/feature2.min.js where the first contains the first 4 files and the second contains the last 2 files.
Is this possible, or am I going to have to manually add those directories to a manifest? It would be really nice to pragmatically iterate over all the directories within /js/.
Thanks for any help you can give me.
-Nate
Edit: It should be noted that I don't only have 2 directories, but I have many (maybe 10-20) so I don't really want to write a task for each directory. I want to handle each directory the same way: get all of the JS inside of it (and any sub-directories) and compile it down to a feature-based minified JS file.
There's an official recipe for this: Generating a file per folder
var fs = require('fs');
var path = require('path');
var merge = require('merge-stream');
var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var scriptsPath = 'src/scripts';
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
gulp.task('scripts', function() {
var folders = getFolders(scriptsPath);
var tasks = folders.map(function(folder) {
return gulp.src(path.join(scriptsPath, folder, '/**/*.js'))
// concat into foldername.js
.pipe(concat(folder + '.js'))
// write to output
.pipe(gulp.dest(scriptsPath))
// minify
.pipe(uglify())
// rename to folder.min.js
.pipe(rename(folder + '.min.js'))
// write to output again
.pipe(gulp.dest(scriptsPath));
});
// process all remaining files in scriptsPath root into main.js and main.min.js files
var root = gulp.src(path.join(scriptsPath, '/*.js'))
.pipe(concat('main.js'))
.pipe(gulp.dest(scriptsPath))
.pipe(uglify())
.pipe(rename('main.min.js'))
.pipe(gulp.dest(scriptsPath));
return merge(tasks, root);
});
You could use glob to get a list of directories and iterate over them, using gulp.src to create a separate pipeline for each feature. You can then return a promise which is resolved when all of your streams have ended.
var fs = require('fs');
var Q = require('q');
var gulp = require('gulp');
var glob = require('glob');
gulp.task('minify-features', function() {
var promises = [];
glob.sync('/js/features/*').forEach(function(filePath) {
if (fs.statSync(filePath).isDirectory()) {
var defer = Q.defer();
var pipeline = gulp.src(filePath + '/**/*.js')
.pipe(uglify())
.pipe(concat(path.basename(filePath) + '.min.js'))
.pipe(gulp.dest(filePath));
pipeline.on('end', function() {
defer.resolve();
});
promises.push(defer.promise);
}
});
return Q.all(promises);
});
I am trying myself to get how streams work in node.
I made a simple example for you, on how to make a stream to filter folders and start a new given stream for them.
'use strict';
var gulp = require('gulp'),
es = require('event-stream'),
log = require('consologger');
// make a simple 'stream' that prints the path of whatever file it gets into
var printFileNames = function(){
return es.map(function(data, cb){
log.data(data.path);
cb(null, data);
});
};
// make a stream that identifies if the given 'file' is a directory, and if so
// it pipelines it with the stream given
var forEachFolder = function(stream){
return es.map(function(data, cb){
if(data.isDirectory()){
var pathToPass = data.path+'/*.*'; // change it to *.js if you want only js files for example
log.info('Piping files found in '+pathToPass);
if(stream !== undefined){
gulp.src([pathToPass])
.pipe(stream());
}
}
cb(null, data);
});
};
// let's make a dummy task to test our streams
gulp.task('dummy', function(){
// load some folder with some subfolders inside
gulp.src('js/*')
.pipe(forEachFolder(printFileNames));
// we should see all the file paths printed in the terminal
});
So in your case, you can make a stream with whatever you want to make with the files in a folder ( like minify them and concatenate them ) and then pass an instance of this stream to the forEachFolder stream I made. Like I do with the printFileNames custom stream.
Give it a try and let me know if it works for you.
First, install gulp-concat & gulp-uglify.
$ npm install gulp-concat
$ npm install gulp-uglify
Next, do something like:
//task for building feature1
gulp.task('minify-feature1', function() {
return gulp.src('/js/feature1/*')
.pipe(uglify()) //minify feature1 stuff
.pipe(concat('feature1.min.js')) //concat into single file
.pipe(gulp.dest('/js/feature1')); //output to dir
});
//task for building feature2
gulp.task('minify-feature2', function() { //do the same for feature2
return gulp.src('/js/feature2/*')
.pipe(uglify())
.pipe(concat('feature2.min.js'))
.pipe(gulp.dest('/js/feature2'));
});
//generic task for minifying features
gulp.task('minify-features', ['minify-feature1', 'minify-feature2']);
Now, all you have to do to minify everything from the CLI is:
$ gulp minify-features
I had trouble with the gulp recipe, perhaps because I'm using gulp 4 and/or because I did not want to merge all my folders' output anyway.
I adapted the recipe to generate (but not run) an anonymous function per folder and return the array of functions to enable them to be processed by gulp.parallel - in a way where the number of functions I would generate would be variable. The keys to this approach are:
Each generated function needs to be a function or composition (not a stream). In my case, each generated function was a series composition because I do lots of things when building each module folder.
The array of functions needs to passed into my build task using javascript apply() since every member of the array needs to be turned into an argument to gulp.parallel in my case.
Excerpts from my function that generates the array of functions:
function getModuleFunctions() {
//Get list of folders as per recipe above - in my case an array named modules
//For each module return a function or composition (gulp.series in this case).
return modules.map(function (m) {
var moduleDest = env.folder + 'modules/' + m;
return gulp.series(
//Illustrative functions... all must return a stream or call callback but you can have as many functions or compositions (gulp.series or gulp.parallel) as desired
function () {
return gulp.src('modules/' + m + '/img/*', { buffer: false })
.pipe(gulp.dest(moduleDest + '/img'));
},
function (done) {
console.log('In my function');
done();
}
);
});
}
//Illustrative build task, running two named tasks then processing all modules generated above in parallel as dynamic arguments to gulp.parallel, the gulp 4 way
gulp.task('build', gulp.series('clean', 'test', gulp.parallel.apply(gulp.parallel, getModuleFunctions())));
`

Gulp synchronous task issue

I'm trying to gather 3 tasks needed to debug in a 1. Of course, since nature of gulp is asynchronous, I have problems with that. So I searched and find a soulution to use run-sequence module for solving that issue. I tried the following code, but it doesn't seem to be working as intended. It's not getting synchronous.
Here's what I tried. Any thoughts guys? I don't want to run all this three commands to complete all the tasks. How can I do that?
var gulp = require('gulp'),
useref = require('gulp-useref'),
gulpif = require('gulp-if'),
debug = require('gulp-debug'),
rename = require("gulp-rename"),
replace = require('gulp-replace'),
runSequence = require('run-sequence'),
path = '../dotNet/VolleyManagement.UI';
gulp.task('debug', function () {
gulp.src('client/*.html')
.pipe(debug())
.pipe(gulp.dest(path + '/Areas/WebAPI/Views/Shared'));
});
gulp.task('rename', function () {
gulp.src(path + '/Areas/WebAPI/Views/Shared/index.html')
.pipe(rename('/Areas/WebAPI/Views/Shared/_Layout.cshtml'))
.pipe(gulp.dest(path));
gulp.src(path + '/Areas/WebAPI/Views/Shared/index.html', {read: false})
.pipe(clean({force: true}));
});
gulp.task('final', function(){
gulp.src([path + '/Areas/WebAPI/Views/Shared/_Layout.cshtml'])
.pipe(replace('href="', 'href="~/Content'))
.pipe(replace('src="', 'src="~/Scripts'))
.pipe(gulp.dest(path + '/Areas/WebAPI/Views/Shared/'));
});
gulp.task('debugAll', runSequence('debug', 'rename', 'final'));
 In gulp you can actually set dependant task. Try this:
gulp.task('debug', function () {
//run debug task
});
gulp.task('rename',['debug'], function () {
//run rename once debug is done
});
I think you are not defining the 'debugAll' task right. Try like this:
gulp.task('debugAll', function () {
runSequence('debug', 'rename', 'final');
});
And also you need to return the stream for those tasks, just add 'return' in front of gulp.src for each of them: debug, rename, final. Here is the example for 'debug' task:
gulp.task('debug', function () {
return gulp.src('client/*.html')
.pipe(debug())
.pipe(gulp.dest(path + '/Areas/WebAPI/Views/Shared'));
});
Both items are mentioned in the docs: https://www.npmjs.com/package/run-sequence

Categories

Resources