How do I make my gulpfile restart when a file is edited? - gulp

right now I have to stop and start this gulp script to clean and rebuild my dist file and then restart the server.
My watch file is clearly wrong, what do I change for it to restart the whole gulp script when a file is edited?
var gulp = require('gulp');
var connect = require('gulp-connect');
var concat = require('gulp-concat');
var clean = require('gulp-clean');
gulp.task('clean', function() {
return gulp.src('app/scripts/dist.js').pipe(clean());
});
gulp.task('scripts', ['clean'], function(){
gulp.src(['app/scripts/app.js', 'app/scripts/**/*.js', 'app/scripts/**/*/*.js'])
.pipe(concat('app/scripts/dist.js'))
.pipe(gulp.dest('.'));
});
gulp.task('webserver', function() {
connect.server();
});
gulp.task('watch', ['scripts'], function(){
gulp.watch('app/scripts' + '*.js', ['scripts']).on('change', function(evt) {
changeEvent(evt);
});
});
gulp.task('default', ['clean','scripts','webserver']);

Your glob for your watch seems to be wrong. Try this:
gulp.watch(['app/scripts/**/*.js', '!app/scripts/dist.js'], ['scripts']).on('change', function(evt) {
changeEvent(evt);
});
Use the exclude pattern for your dist.js to avoid an infinite loop.
Ciao
Ralf

In addition to my comment above:
Instead of setting your default task as the 3 tasks you have listed, do it like this.
gulp.task('watch',function(){
var scripts=gulp.watch(//scripts array,['scripts']);
scripts.on('change,function(evt){
changedEvt(evt) // remember to make sure this exists.
});
gulp.task('default',['watch']);
/* make sure to include watches for all the logic you want to get
executed within your watch tasks (similar to how I did it)
#== That way, you can still call those tasks from a different shell prompt
if you want, but they are set to always be executed when you
modify the related files.
*/

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

Getting gulp and es6 set up to reload on saves

I have been playing with gulp and babel for the past few days. I am getting a solid grasp of setting up babel with gulp through tutorials. I've noticed that the newer the tutorial the more changes that develop.
Here is one way I was able to set up es6 to es5 with a transpiler.
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task('es6to5', function () {
return gulp.src('js/src/app.js')
.pipe(babel())
.pipe(gulp.dest('dist'));
});
However, I do not want to rerun gulp each time, and I want the dist/ folder to update on each save.
I added browser-sync and delete.
var gulp = require('gulp');
var babel = require('gulp-babel');
var browserSync = require('browser-sync');
var del = require('del');
gulp.task('clean:dist', function() {
return del([
'dist/app.js'
]);
});
gulp.task('es6to5', function () {
return gulp.src('js/src/app.js')
.pipe(babel())
.pipe(gulp.dest('dist'));
});
gulp.task("browserSync", function() {
browserSync({
server: {
baseDir: './dist'
}
});
});
gulp.task("copyIndex", ['clean:dist'], function() {
gulp.src("src/index.html")
.pipe(gulp.dest('./dist'))
.pipe(browserSync.reload({stream: true}));
});
gulp.task('watchFiles', function() {
gulp.watch('src/index.html', ['copyIndex']);
gulp.watch('src/**/*.js', ['babelIt']);
});
gulp.task('default', ['clean:dist', 'es6to5','browserSync','watchFiles']);
I set up a default that will clean out the dist folder then run es6to5. Afterwards I want it to sync and update. I called watchFiles last.
However, I am no longer getting updated js files. The files in the dist folder Are not compiling to es5 and everything is going to a 404.
The task
copyIndex seems to be the problem but I am not sure how to fix it or if it is the only problem. Any direction helps.
You have a typo.
It should be gulp.watch('src/**/*.js', ['es6to5']);, not gulp.watch('src/**/*.js', ['babelIt']);
Anyway i suggest to use gulp-watch instead of the built-in watch function. It has several advantages, mainly it recompile on new file creation.

Copy/Deletion in Gulp randomly gives ENOENT

New to Gulp. My default task is using the pluginrun-sequence which tells task deleteBuild to run, then makeBuild.
Randomly, I am getting an ENOENT error which seems to be telling me that I'm either referencing files that don't exist for deletion or copy. My tasks are:
deleteBuild:
gulp.task('deleteBuild', function(done) {
var del = require('del');
del(['build/**/*'], done);
});
makeBuild:
gulp.task('makeBuild', function() {
var stream = gulp.src(['src/**/*'], { base: 'src/' })
.pipe(gulp.dest('build/');
});
Can someone inform me as to how to best address this issue? I'm hoping to seek a low-level understanding rather than to be shown a solution w/o an explanation. Thanks.
Aside: I tried the deleteBuild without a callback function as well, under the assumption that, as is, it would perform the deletion and only continue to the next task once it is complete, though this doesn't seem to be what is happening.
That's probably because the deleteBuild does not return a gulp stream and thus leave the pipe broken. I would propose the following:
gulp.task('deleteBuild', function() {
var del = require('del');
var vinylPaths = require('vinyl-paths');
return gulp.src(['build']) // no need for glob, just delete the build directory
.pipe(vinylPaths(del));
});
gulp.task('makeBuild', function() {
var stream = gulp.src(['src/**/*'], { base: 'src/' })
.pipe(gulp.dest('build/');
});
gulp.task('default', function(cb) {
var runSequence = require('run-sequence');
runSequence('deleteBuild', ['makeBuild'], cb);
});
These tasks will first delete the build directory before executing the makeBuild task.
You'll need to install one additional plugin:
npm install vinyl-paths
For a ready to use example, please take a look a the gulpfile of skeletonSPA. This works for me ;-)