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.
Related
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);
});
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.
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.
I want to just build 'the only one file' I changed,not a bunch of files,
so I tried something like this
gulp.task('watch_html', function () {
return gulp.watch('source/**/*.html', function (event) {
gulp.src(event.path)
.pipe(prettify({indent_size: 4}))
.pipe(gulp.dest('dist'));
});
});
But why this won't work?
Is there a workaround?
I think a gulp package like gulp-changed may be able to help you out.
It provides a way to only operate on changed files in a stream. Check it out here.
Hope that helps!
You should separate the tasks :
gulp.task('html', function() {
return gulp.src('source/**/*.html')
.pipe(prettify({indent_size: 4}))
.pipe(gulp.dest('dist'));
});
gulp.task('watch', function() {
// when modification is detected, html task is launched
gulp.watch(['source/**/*.html'], ['html']);
});
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.
*/