I have gulp watch set like this:
gulp.watch(somepath, {interval: 500}, ['buildScripts']);
And the build scripts looks like this:
gulp.task('buildScripts', function (path) {
//compiles the file from watch
});
How can I pass the value of changed file/files so that the buildScripts can compile those files?
You'll have to factor out your buildScripts code into its own function and call that function from both your watch and task. If you don't need the task you can just drop it, of course.
var gulp = require('gulp');
function buildScripts(changedFile) {
if (changedFile) {
// called from watch
// compile the changed file
} else {
// called from task
// compile all files
}
}
gulp.task('buildScripts', function() {
return buildScripts();
});
gulp.task('watch', function() {
gulp.watch('*.js', {interval:500}, buildScripts);
});
Related
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');
});
});
My gulpfile 4 works fine. But I am just slightly curious why I need no on('change'....) when invoking a method calling a browserSync.stream()
Below is my Gulp4 gulpfile and it works fine
But I am curious as to why, in the watch method below, my sass watch does not require an onchange handler.
If I where to remove the change handler from the watch of my script and html files and try to call reload directly, then those two will no longer work.
Yet, the sass watch requires none. Hmm. Why.
Here is the code
const gulp = require("gulp");
const sass = require("gulp-sass");
const postcss = require("gulp-postcss");
const autoprefixer = require("autoprefixer");
const sourcemaps = require("gulp-sourcemaps");
const browserSync = require("browser-sync").create();
const paths = {
styles: {
src: "src/scss/*.scss",
dest: "src/css"
},
scripts: {
src: "src/js/*.js"
},
watched: {
src: "src/*.html"
}
};
function style() {
return gulp
.src(paths.styles.src)
//Sourcemaps first so we get mapping once the compilation is done
.pipe(sourcemaps.init())
.pipe(sass())
.on("error", sass.logError)
//Sass one now run auto prefix
.pipe(postcss([autoprefixer]))
//Write the sourcemap
.pipe(sourcemaps.write())
.pipe(gulp.dest(paths.styles.dest))
.pipe(browserSync.stream());
}
//Parallell to this, we need a watch task for the Scss
function watch() {
browserSync.init({
server: {
baseDir: "./src"
}
});
//Watch JavaScript files; just calling reload directly at the moment as we're not babeling
gulp.watch(paths.scripts.src).on('change', reload);
//Watch Sass files
gulp.watch(paths.styles.src, style)
//Lets make the html our trigger for reload as set in paths object above
gulp.watch(paths.watched.src).on('change', reload);
}
function reload() {
browserSync.reload();
}
//Expose to npm
exports.watch = watch;
exports.style = style;
// Default task invoked by typing 'gulp' in npm
gulp.task('default', gulp.parallel(style, watch))
Thanks in advance, I owe you a glass of Madeira.
Thomas
You can call reload directly, but gulp needs a way of knowing when the task is finished. Adding a callback should do the trick:
function reload(cb) {
browserSync.reload();
cb();
}
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')
)
);
So I'm trying to create a gulp workflow and I'd like to implement options for some tasks, like gulp copy-images --changed. Now, I've created a watch task that obviously watches all image files and it should start the copy-images with the --changed flag.
Ideally, I want to do something like this:
gulp.task('copy-images', function(){
// some code
});
gulp.task('watch', function(){
gulp.watch(config.images, ['copy-images --changed']);
});
I'm also very aware that I could do:
gulp.task('copy-images', function(){
// some code
});
gulp.task('copy-images-changed', function(){
// some code
});
gulp.task('watch', function(){
gulp.watch(config.images, ['copy-images']);
});
but this means duplicate code.
Anyone with a solution or maybe some advice?
Thanks in advance!
Gulp does not provide a built-in way of specifying options for tasks. You have to use an external options parser module like yargs. See this question for more on that topic.
This also means that passing something like ['copy-images --changed'] to gulp.watch() will not work. The entire string will just be interpreted as a task name.
The best approach for you would be to factor out the code of your task into a function and then call this function from both your task and your watch:
var argv = require('yargs').argv;
function copyImages(opts) {
if (opts.changed) {
// some code
} else {
// some other code
}
}
gulp.task('copy-images', function() {
copyImages(argv);
});
gulp.task('watch', function(){
gulp.watch(config.images, function() {
copyImages({changed:true});
});
});
The above should cover all of your bases:
gulp copy-images will execute //some other code.
gulp copy-images --changed will execute //some code.
gulp watch will execute //some code any time a watched file is changed.
I have a Gulp task that uses glob-stream to recursively loop through directories and files to perform a task, similar to below, but far more elaborate:
var gs = require('glob-stream');
var config = {
PATH: 'some/path/*.*'
}
function doSomething(filePath) {
var stream = gs.create(filePath);
// Do something
return gs.on('data', doSomething);
}
gulp.task('compile', function() {
var filePath = config.PATH;
return doSomething(filePath);
});
I can have the task achieve the results and compile what I need, but unfortunately Gulp believes the task has finished while it's still running, causing issues in my build process - How can I avoid this? I'm already using run-sequence but to no effect.
Why are you manually walking the directory tree with a recursive function? Why not just let glob-stream do the work for you? Then you only have to take care of the //Do something part:
var config = {
PATH: 'some/path/**' //glob pattern for all subfolder and files
};
function doSomething(filePath) {
//Do something
}
gulp.task('compile', function() {
var stream = gs.create(config.PATH);
stream.on('data', doSomething);
return stream;
});
gulp.task('secondTask', function() {
console.log('secondTask');
});
gulp.task('default', function() {
runSequence('compile', 'secondTask');
});
The some/path/** glob pattern creates a stream of all folders and files below some/path/, so you don't have to implement the recursive tree walk yourself.
Note that the compile task returns the stream. Otherwise gulp can't tell when the compile task has completed and starts running secondTask before compile has finished.