I'm watching for changes on files like this:
gulp.watch(['./src/js/**/*', './src/templates/**/*', config.vendor.js], ['js']);
Part of my build process involves using the "angular-filesort" module (don't think this is important though). If I implement the task as follows and use plumber, when filesort fails gulp doesn't quit and "watch" will keep checking for updates which is what I want:
gulp.task('js', function() {
gulp.src('./src/js/**/*.js').pipe(plumber()).pipe(angularFilesort());
});
However, if I wrap up this process in a streamqueue, gulp will exit when filesort fails which I don't want:
gulp.task('js', function() {
streamqueue({
objectMode: true
},
gulp.src('./src/js/**/*.js').pipe(plumber()).pipe(angularFilesort())
)
});
How can I fix this?
Specifically, I'm doing something like this to process 3 different sets of JavaScript files then concating them:
streamqueue({
objectMode: true
},
gulp.src(config.vendor.js),
gulp.src('./src/js/**/*.js').pipe(angularFilesort()),
gulp.src(['src/templates/**/*.html']).pipe(templateCache({
module: mainAngularModuleName
})))
.pipe(sourcemaps.init())
.pipe(concat('app.js'))
etc.
Is there perhaps a way I can do the above without streamqueue to work around this issue?
I had a similar issue and switching from streamqueue to stream-series resolved it for me. It's also cleaner than streamqueue because you don't need to specify the object mode.
I found reinstalling node and upgrading all my packages fixed this.
Related
I am using Gulp 4 to compile my code from TypeScript to JavaScript and to build and serve the app.
I've come across one problem that I cannot solve.
I'd like to run the build, copy-html and copy-css tasks before some file gets changed.
According to Gulp documentation I just need to provide a config object with ignoreInitial set to false, but it doesn't work.
I've tried to call the three tasks before I initialize browserSync but for it also didn't work for me.
gulp.task("serve", function() {
// TODO Make a build before first serve
browserSync.init({
server: {
baseDir: "./dist/"
}
});
gulp
.watch(["src/**/*.ts", "src/**/*.html", "src/**/*.css"], {
ignoreInitial: false
})
.on(
"change",
gulp.series(
gulp.parallel("copy-html", "copy-css"),
build,
browserSync.reload
)
);
});
Instead of using calling .on() on the returned chokidar interface, add your tasks to the watch command.
gulp
.watch(
["src/**/*.ts", "src/**/*.html", "src/**/*.css"],
{ ignoreInitial: false },
gulp.series(
gulp.parallel("copy-html", "copy-css"),
build,
browserSync.reload
)
)
);
There is a bug in following gulp stream but I just couldn't find where.
var processors = [autoprefixer({ browsers: ['last 2 version']}),
cssnano(),];
var myjob = gulp.src(['app/css/normalize.css',
'app/css/org.scss'])
.pipe(watch('app/css/org.scss', {verbose: true}))
.pipe(gulpif('*.scss', sass()))
.pipe(concat('org.css'))
.pipe(postcss(processors))
.pipe(flatten())
.pipe(gulp.dest('dist'));
Problem: The dist/org.css is not regenerated
there must be something I'm missing here.
The problem is that gulp-concat doesn't push the concatenated org.css file unless it receives an end event from upstream. Since gulp-watch never emits the end event, gulp-concat just hangs indefinitely.
The solution is to simply replace gulp-concat with gulp-continuous-concat:
var continuousConcat = require('gulp-continuous-concat');
var processors = [autoprefixer({ browsers: ['last 2 version']}),
cssnano(),];
gulp.task('default', function() {
return gulp.src(['app/css/normalize.css',
'app/css/org.scss'])
.pipe(watch('app/css/org.scss', {verbose: true}))
.pipe(gulpif('*.scss', sass()))
.pipe(continuousConcat('org.css'))
.pipe(postcss(processors))
.pipe(flatten())
.pipe(gulp.dest('dist'));
});
As a best practice use the glob root "./" to prefix your paths. i.e. "./app/css/normalize.css" and so on.
Try and use gulp-debug to see how many files are in the pipe, if any. You can add a debug pipe between each step to see what's going on.
So I'm having a slight problem with producing production ready scripts for my project. I'm using gulp to concatenate and minify my css and js, and while the css is working fine the gulp js function isn't generating my final file. Please refer to my code below:
gulp.task('js', function() {
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(gulp.dest(source + 'js'))
.pipe(rename({
basename: 'production',
suffix: '-min',
}))
.pipe(uglify())
.pipe(gulp.dest(source + 'js/'))
.pipe(notify({ message: 'Scripts task complete', onLast: true }));
});
If anyone has encountered a similar problem or has any tips it would be much appreciated :)
There is nothing wrong with your gulpfile. I tested it and it works perfectly.
The only thing I can guess is that your source is not set correctly. Did you forget the trailing slash '/' ?
I would suggest 2 things to figure it out. Include node path library to check where source is actually pointing to like this:
var path = require('path');
// in gulp task ...
path.resolve(path.resolve(source + 'js/app'));
Make sure it points where you think it does.
Secondly, you could use gulp-debug to establish that any files are found:
npm install gulp-debug
Then
var debug = require('gulp-debug');
// in gulp task ...
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(debug())
.pipe(gulp.dest(source + 'js'))
.pipe(debug())
// etc.
Good luck!
Based on additional infomation in the comments I realise you are generating JS files in a separate process ...
gulp is asynchronous by default. What this boils down to is that all functions try to run at the same time - if you want a specific order it must be by design. This is great because it's very fast but can be a headache to work with.
Problem
Here is what's basically happening:
// SOME TASK THAT SHOULD BE RUN FIRST
gulp.task('copy-vendor-files-to-tempfolder', function (done) {
// copy files to vendor folder
done()
})
// SOME TASKS THAT DEPEND ON FIRST TASK
gulp.task('complile-styles', function () { /* independent task */ })
gulp.task('concat-vendor-files', function () { /* concat files in vendor folder. depends on vendor files existing */ })
// GENERAL TASK WHICH STARTS OTHERS
gulp.task('ready', ['copy-vendor-files-to-tempfolder', 'compile-styles', 'concat-vendor-files])
When you try to run:
$ gulp ready
GULP TASK WILL FAIL! Folder is being created at the same time!!
NOWHERE TO COPY FILES!
Solution
There are many solutions but the following module has come in handy for me again and again:
npm install run-sequence
Then in your gulpfile.js:
var runSequence = require('run-sequence')
gulp.task('ready', function (done) {
runSequence(
'create-folders', // do this first,
[
'copy-css-files',
'copy-html-files'
], // do these AFTER but in parallel
done // callback when ready
)
})
This will guarantee the folder exists when you try to run the other functions.
In your specific case, you should make sure the task that concatenates the JS files is run after the task that copies them out of vendor.
Note: I'm leaving other answer because it contains useful help for debugging similar issues.
HTH!
Using Gulp to streamline my build process on a per-save basis, while eliminating the need for "temp" files is my goal (and why I chose to use Gulp over Grunt)
I've recently discovered that, apparently, the coffeescript compiler cannot handle dealing with basic Javascript as a source
So this, errors out:
gulp.task('scripts', function() {
var stream =
gulp.src([
"bower_components/d3/d3.js",
"bower_components/angular/angular.js",
"bower_components/foundation/js/foundation.js",
"public-dev/scripts/app.js",
"public-dev/scripts/**/*.js",
"public-dev/scripts/**/*.coffee"
])
.pipe(coffee())
.pipe(concat('compiled.js'))
.pipe(gulp.dest('./public/scripts'))
;
return stream;
});
This produces the output/errpr:
[11:58:51] Starting 'scripts'...
events.js:72
throw er; // Unhandled 'error' event
^
/var/www/node.fortiguard.dev/bower_components/d3/d3.js:1:2: error: reserved word "function"
!function() {
^
How should I set this up, without again creating any temp files?
What I liked about the LESS compiler, is that it can still be fed straight CSS files and it'd be fine. I was kind of hoping the Coffee compiler would react the same way
I use gulp-add-src to do that.
var gulp = require('gulp'),
coffee = require('gulp-coffee'),
concat = require('gulp-concat'),
addsrc = require('gulp-add-src');
// Scripts
gulp.task('coffee', function () {
return gulp.src('src/coffee/**/*.coffee')
.pipe(coffee())
.pipe(addsrc('src/coffee/lib/*.js'))
.pipe(concat('compiled.js'))
.pipe(gulp.dest('dist'));
});
Sadly, it doesn't. What you can do, is using the underlying event-stream's merge method. Then you'll have one pipeline for the coffee files that gets compiled and one for the javascript side.
Here is an example Gulpfile.coffee:
coffee = require 'gulp-coffee'
es = require 'event-stream'
gulp.task 'scripts', () ->
es.merge(
gulp.src(["public-dev/app.js", "public-dev/scripts/**/*.js"]) # ...
gulp.src("public-dev/**/*.coffee").pipe coffee()
)
.pipe concat 'all.js'
.pipe gulp.dest "build"
I marked Patrick J. S.'s answer as "Correct" becuase in reality, this is exactly what I needed to do.
That said, "event-stream" isn't what I ended up going with, simply because I needed to preserve my dependency structure of files, and event-stream's merge() method does not preserver order nor does it have options to.
Instead I opted for a package called streamqueue, which does preserve order of glob. Probably slower, but order matters in my app unfortunately. In the future I will try to be as modular as possible.
I've got some tasks already defined in gulpfile.js and I want to use gulp-watch plugin (to run tasks on new files). My question is, because I couldn't find anything, can I run my existing tasks while running watch (from plugin) function?
var gulp = require('gulp'),
watch = require('gulp-watch'),
...;
gulp.task('lint', function () {
return gulp.src(path.scripts)
.pipe(jshint())
.pipe(jshint.reporter(stylish));
});
gulp.task('watch', function () {
watch({ glob: 'app/**/*.js' }); // Run 'lint' task for those files
});
Because I don't want to include watch() task in every task I have. I would like to have only 1 task - watch, which will combine all "watches".
----- EDIT ----
(as I probably didn't quite get my point):
I need to run task from inside of gulp('watch') task. for example:
like I did it with gulp.watch:
gulp.task('watch', function () {
gulp.watch('files', ['task1', 'task2']);
});
I need to do the same but with gulp-watch plugin, something like (I know it wouldn't work):
var watch = require('gulp-watch');
gulp.task('watch', function () {
watch({ glob: 'files' }, ['task1', 'task2']);
});
I have also run into the problem of wanting to use gulp-watch (not gulp.watch), needing to use the callback form, and having trouble finding a suitable way to run a task in the callback.
My use case was that I wanted to watch all stylus files, but only process the main stylus file that includes all the others. Newer versions of gulp-watch may address this but I'm having problems with 4.3.x so I'm stuck on 4.2.5.
gulp.run is deprecated so I don't want to use that.
gulp.start works well, but is also advised against by the gulp author, contra.
The run-sequence plugin works well and lets you define a run
order, but it is a self-proclaimed hack:
https://www.npmjs.com/package/run-sequence
Contra suggest writing plain old functions and calling
those. This is a new idea to me, but I think the example below captures the idea. https://github.com/gulpjs/gulp/issues/505
Take your pick.
var gulp = require('gulp'),
watch = require('gulp-watch'), // not gulp.watch
runSequence = require('run-sequence');
// plain old js function
var runStylus = function() {
return gulp.src('index.styl')
.pipe(...) // process single file
}
gulp.task('stylus', runStylus);
gulp.task('watch', function() {
// watch many files
watch('*.styl', function() {
runSequence('stylus');
OR
gulp.start('stylus');
OR
runStylus();
});
});
All of these are working for me without warnings, but I'm still unsure about getting the "done" callback from the 4.2.x version of gulp-watch.
You will most likely want to run specific tasks related to the files you are watching -
gulp.task('watch',['lint'], function () {
gulp.watch('app/**/*.js' , ['lint']);
});
You can also use the ['lint'] portion to run any required tasks when watch first gets called, or utilize the tasks to run async with
gulp.task('default', ['lint','watch'])
You can just call one task, that then includes both task
gulp.task('default', ['lint','watch'])
so here you would just call 'gulp'
gulp.task('watch', function() {
watch(files, function() {
gulp.run(['task1', 'task2']);
});
});
work fine, except a warning