How to add a watch to a folder in gulp - javascript

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.

Related

Trouble with splitting gulpfile.js into multiple files in Gulp 4

I am a beginner to Javascript and Gulp. Am learning this based on a udemy course in which Gulp 3 is being used, and I've been looking at docs to convert the code to Gulp 4. It's been fun so far since I am learning more when I am doing the conversions myself, but am stuck on this one. Wonder if you guys can offer some advice.
Issue: When I split the gulpfile.js into separate files to organise my files better, it starts throwing errors. Code below.
styles.js
var gulp = require('gulp'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import');
function styles(cb) {
return gulp.src('./app/assets/styles/styles.css')
.pipe(postcss([cssImport, cssvars, nested, autoprefixer]))
.pipe(gulp.dest('./app/temp/styles'));
cb();
}
exports.styles = styles;
watch.js
var gulp = require('gulp'),
browserSync = require('browser-sync').create();
function cssInject(cb) {
return gulp.src('./app/temp/styles/styles.css')
.pipe(browserSync.stream());
cb();
}
function browserSyncReload(cb) {
browserSync.reload();
cb();
}
function watch(cb) {
browserSync.init({
notify: false,
server: {
baseDir: "app"
}
});
watch('./app/index.html', browserSyncReload);
watch('./app/assets/styles/styles.css', gulp.series(cssInject, styles));
cb();
}
exports.browserSyncReload = browserSyncReload;
exports.watch = watch;
gulpfile.js
var stylesTasks = require('./gulp/tasks/styles.js'),
watchTasks = require('./gulp/tasks/watch.js');
exports.watch = watchTasks.watch;
exports.styles = stylesTasks.styles;
exports.browserSyncReload = watchTasks.browserSyncReload;
When I run "gulp watch", this is what I get.
error
$ gulp watch
[21:14:28] Using gulpfile ~/Projects/travel-site/gulpfile.js
[21:14:28] Starting 'watch'...
internal/async_hooks.js:195
function emitInitNative(asyncId, type, triggerAsyncId, resource) { ^
RangeError: Maximum call stack size exceeded
(Use `node --trace-uncaught ...` to show where the exception was thrown)
I found another post with almost identical code, but with a different error - which happened to be one of the errors i was getting earlier as well, and have followed the solution mentioned in that post - and that's when I get this error. Here's the link to the post.
Any help is much appreciated. Thanks for your time.
I have a full article that shows many how to regarding going from gulp3 to gulp4, I think you are going to find everything you need there
But basically, I think you need to take a look at these modules :
gulp-task-loader-recursive
gulp4-run-sequence
require-dir
Then, from a gulp.js perspective, you can end up with something like this :
// gulpfile.js
global.config = require('./gulp/config/config.json');
require('events').EventEmitter.prototype._maxListeners = 1000;
require('require-dir')('./gulp/tasks/styles');
require('require-dir')('./gulp/tasks/watch');
//... etc ...
So you would be able to then create your styles task and export it :
var gulp = require('gulp'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import');
function styles(cb) {
return gulp.src('./app/assets/styles/styles.css')
.pipe(postcss([cssImport, cssvars, nested, autoprefixer]))
.pipe(gulp.dest('./app/temp/styles'));
cb();
}
const stylesTask = task('styles', styles);
exports.stylesTask = stylesTask;
You can then validate its recognized by gulp :
gulp --tasks
If you correctly see your styles tasks, you should now be able to run your task by running :
gulp styles
Repeat those steps for the watch task.
Answering my own question feels wierd, but I found the solution after playing with it for couple of days. See below.
I needed to import styles into watch.js, and not gulpfile.js. That was my first mistake. To do this, I added the below line to watch.js
var styles = require('./styles').styles;
Then my gulpfile.js only needed two lines
gulpfile.js
var watchTask = require('./gulp/tasks/watch').watch;
exports.default = watchTask;
I also removed the variable gulp, instead created variables for src and dest. So, the rest of the code looked like below.
styles.js
var {src, dest} = require('gulp'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import');
const styles = function (cb) {
return src('./app/assets/styles/styles.css')
.pipe(postcss([cssImport, cssvars, nested, autoprefixer]))
.pipe(dest('./app/temp/styles'));
cb();
}
exports.styles = styles;
watch.js
var styles = require('./styles').styles;
var {src, series, watch} = require('gulp'),
browserSync = require('browser-sync').create();
const cssInject = function (cb) {
return src('./app/temp/styles/styles.css')
.pipe(browserSync.stream());
cb();
}
const reload = function (cb) {
browserSync.reload();
cb();
}
const watchTask = function (cb) {
browserSync.init({
notify: false,
server: {
baseDir: "app"
}
});
watch('./app/index.html', reload);
watch('./app/assets/styles/styles.css', series(cssInject, styles));
cb();
}
exports.watch = watchTask;
Hence resolved! hope this helps someone else.

How to make Gulp watch monitoring files?

I have a simple gulpfile.js, that defines only two tasks, buildLess and watchFiles:
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var filter = require('gulp-filter');
function buildLess(done) {
const fileFilter = filter(['**/*', '!**/mixins.less', '!**/variables.less']);
gulp.src('./public/less/*.less')
.pipe(fileFilter)
.pipe(plumber())
.pipe(less())
.pipe(gulp.dest('./public/css/'))
;
done();
};
function watchFiles() {
gulp.watch(['public/less/*.less'], gulp.series('build-less'));
// gulp.watch(['./public/less/*.less'], gulp.series(buildLess));
};
gulp.task('build-less', buildLess);
gulp.task('watch-files', watchFiles);
The first one ($ gulp build-less) is working fine. The watchFiles ($ gulp watch-files) can be started and doesn't cause any errors, but changes on the public/less/style.less are ignored.
What is wrong at this gulpfile.js and how to get the watch-files task working?
The gulp.series API allows you to pass a string of a previously registered task. In your code, you haven't registered build-less yet.
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var filter = require('gulp-filter');
function buildLess(done) {
const fileFilter = filter(['**/*', '!**/mixins.less', '!**/variables.less']);
gulp.src('./public/less/*.less')
.pipe(fileFilter)
.pipe(plumber())
.pipe(less())
.pipe(gulp.dest('./public/css/'))
;
done();
};
gulp.task('build-less', buildLess);
function watchFiles() {
gulp.watch(['public/less/*.less'], gulp.series('build-less'));
// gulp.watch(['./public/less/*.less'], gulp.series(buildLess));
};
gulp.task('watch-files', watchFiles);
I would note that Gulp does not recommend using the gulp.task API anymore to register tasks, but instead to use exports.
Secondly, you don't need gulp-watch, as gulp now comes with its own gulp.watch method (which you are already using).
Lastly, you should make sure to your correctly signaling async completion in your buildLess function. Below, I've changed that function to return a Stream, rather than calling a done() callback since as you have it written, you have a race condition where done() may be called before the Less compilation has finished.
var gulp = require('gulp');
var less = require('gulp-less');
var plumber = require('gulp-plumber');
var filter = require('gulp-filter');
function buildLess() {
const fileFilter = filter(['**/*', '!**/mixins.less', '!**/variables.less']);
return gulp
.src('./public/less/*.less')
.pipe(fileFilter)
.pipe(plumber())
.pipe(less())
.pipe(gulp.dest('./public/css/'));
}
exports['build-less'] = buildLess;
function watchFiles() {
gulp.watch(['public/less/*.less'], buildLess);
}
exports['watch-files'] = watchFiles;
Overall, I'd go through Gulp's documentation. They recently updated their website, and updated their documentation along with it. Going through that might clear up some other questions you may be having.

gulp-load-plugins.sourcemaps.init() TypeError: Cannot read property 'init' of undefined

I'm trying to adapt a gulp file to my purposes and I'm running into issues. I only care about one task:
gulp.task('js:browser', function () {
return mergeStream.apply(null,
Object.keys(jsBundles).map(function(key) {
return bundle(jsBundles[key], key);
})
);
});
It is using browserify to condense my bundle into a usable single file. It uses these two methods and this object:
function createBundle(src) {
//if the source is not an array, make it one
if (!src.push) {
src = [src];
}
var customOpts = {
entries: src,
debug: true
};
var opts = assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts));
b.transform(babelify.configure({
stage: 1
}));
b.transform(hbsfy);
b.on('log', plugins.util.log);
return b;
}
function bundle(b, outputPath) {
var splitPath = outputPath.split('/');
var outputFile = splitPath[splitPath.length - 1];
var outputDir = splitPath.slice(0, -1).join('/');
console.log(outputFile);
console.log(plugins);
return b.bundle()
// log errors if they happen
.on('error', plugins.util.log.bind(plugins.util, 'Browserify Error'))
.pipe(source(outputFile))
// optional, remove if you don't need to buffer file contents
.pipe(buffer())
// optional, remove if you dont want sourcemaps
.pipe(plugins.sourcemaps.init({loadMaps: true})) // loads map from browserify file
// Add transformation tasks to the pipeline here.
.pipe(plugins.sourcemaps.write('./')) // writes .map file
.pipe(gulp.dest('build/public/' + outputDir));
}
var jsBundles = {
'js/polyfills/promise.js': createBundle('./public/js/polyfills/promise.js'),
'js/polyfills/url.js': createBundle('./public/js/polyfills/url.js'),
'js/settings.js': createBundle('./public/js/settings/index.js'),
'js/main.js': createBundle('./public/js/main/index.js'),
'js/remote-executor.js': createBundle('./public/js/remote-executor/index.js'),
'js/idb-test.js': createBundle('./public/js/idb-test/index.js'),
'sw.js': createBundle(['./public/js/sw/index.js', './public/js/sw/preroll/index.js'])
};
When I run the gulp task js:bower I get the following error coming from the the .pipe(plugins.sourcemaps.init({loadMaps: true})) expression:
TypeError: Cannot read property 'init' of undefined
I know that the lines are optional and I can just comment them out, but I do want them. When I run the code in the example file it works properly, when I run it in my gulp file it gives me the error. Any suggestions on what I might be missing? Thanks!
gulp-load-plugins analyzes the contents of your package.json file to find out which Gulp plugins you have installed. Make sure that gulp-sourcemaps is among the "devDependencies" defined there. If not run
npm install --save-dev gulp-sourcemaps
There's a small chance that your problem is related to lazy loading the sourcemaps plugin. If the above doesn't help try requiring gulp-load-plugins like this:
var plugins = require('gulp-load-plugins')({lazy:false});

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'.

gulp-jscs seems to be unable to detect the config (.jscsrc) file, but normal jscs can from the command line

When I run "gulp style" from the command line, Gulp runs, and, subsequently, gulp-jscs runs, but the latter seems to be unable to detect the rules defined in the jscs config file (.jscsrc). But, if I run jscs from the command line, then jscs does detect the config file's rules. Any idea what the deal could be?
Here's my gulp file:
(function() {
"use strict";
var gulp = require("gulp");
var jshint = require("gulp-jshint");
var jscs = require("gulp-jscs");
var jsFiles = ["*.js", "src/**/*.js"];
gulp.task("style", function () {
console.log("Running the style task.");
return gulp.src(jsFiles)
.pipe(jshint())
.pipe(jshint.reporter("jshint-stylish", {
verbose: true
}))
.pipe(jscs({configPath: "./.jscsrc"}));
});
})();
You need a reporter (just like jshint has one):
var gulp = require("gulp");
var jshint = require("gulp-jshint");
var jscs = require("gulp-jscs");
var jsFiles = ["*.js", "src/**/*.js"];
gulp.task("style", function () {
console.log("Running the style task.");
return gulp.src(jsFiles)
.pipe(jshint())
.pipe(jshint.reporter("jshint-stylish", {
verbose: true
}))
.pipe(jscs({configPath: "./.jscsrc"}))
.pipe(jscs.reporter()); // << this line here
});
Other notes, (if you are running from cmd), Gulpfile.js you don't need to wrap it into anonymous function or use 'use strict'.
Example output:
[13:53:30] Using gulpfile C:\del\so\gulpjscs\Gulpfile.js
[13:53:30] Starting 'style'...
Running the style task.
[13:53:31] gulp-debug: Gulpfile.js
[13:53:31] gulp-debug: index.js
[13:53:31] gulp-debug: 2 items
Comments must start with a lowercase letter at C:\del\so\gulpjscs\index.js :
1 |// Invalid
--------^
2 |// valid
3 |
1 code style error found.
[13:53:31] Finished 'style' after 187 ms
If you're not sure how will current path ./ be taken into account you can always use path module to resolve, for example:
var path = require('path');
var configPath = path.resolve(path.join(__dirname, '.jscsrc'))

Categories

Resources