After 'html' task file index.html still not exists in Gulp - configuration

I run simple configuration:
gulp.task('html', function() {
gulp.src(config.paths.html)
.pipe(gulp.dest(config.paths.dist))
.pipe(connect.reload());
});
gulp.task('connect', function() {
server.listen(config.port);
lrserver.listen(config.livereloadport);
});
gulp.task('open', ['connect'], function() {
gulp.src('dist/index.html')
.pipe(open({ uri: config.devBaseUrl + ':' + config.port + '/'}));
});
gulp.task('default', ['html', 'open']);
But, the first time on 'open' task file index.html still not exists and only the second time it is created and task 'open' will execute successful. What's wrong with my configuration?
I've add a console log:
D:\Projects\demo>gulp
[11:01:13] Using gulpfile D:\Projects\demo\gulpfile.js
[11:01:13] Starting 'connect'...
[11:01:13] Finished 'connect' after 4.33 ms
[11:01:13] Starting 'html'...
[11:01:13] Finished 'html' after 9.03 ms
[11:01:13] Starting 'open'...
[11:01:13] Finished 'open' after 3.14 ms
[11:01:13] Starting 'default'...
[11:01:13] Finished 'default' after 9.82 μs

Your tasks depends on each other. You should make 'open' depends on 'html' so ot will wait for it to finish:
gulp.task('html', function() {
gulp.src(config.paths.html)
.pipe(gulp.dest(config.paths.dist))
.pipe(connect.reload());
});
gulp.task('connect', function() {
server.listen(config.port);
lrserver.listen(config.livereloadport);
});
gulp.task('open', ['connect', 'html'], function() {
gulp.src('dist/index.html')
.pipe(open({ uri: config.devBaseUrl + ':' + config.port + '/'}));
});
gulp.task('default', ['open']);

So, I found the solution. By default all tasks in gulp are running in parallel. So, you need the task dependency if you want to run them in series, as answered eburger before:
gulp.task('open', ['connect', 'html'], function() {
gulp.src('dist/index.html')
.pipe(open({ uri: config.devBaseUrl + ':' + config.port + '/'}));
});
But beside this you need also get gulp to know when the previous task will has been finished (added return):
gulp.task('html', function() {
return gulp.src(config.paths.html)
.pipe(gulp.dest(config.paths.dist))
.pipe(connect.reload());
});
This solved my issue.

Related

Returning a stream but still getting error "Did you forget async completion?" Gulp 4

I am building a website on gulp, this code snippet basically contains 3 tasks browser-sync jekyll-build stylus, browser-sync task depends upon jekyll-build.
browser-sync works fine but the stylus function in which I am returning a stream is giving a error which is not expected.
Below is my code snippet.
I am returning a stream here which is one of the solutions mentioned in the doc Async Completion but still I get the error.
var gulp = require('gulp'),
plumber = require('gulp-plumber'),
browserSync = require('browser-sync'),
stylus = require('gulp-stylus'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'),
jeet = require('jeet'),
rupture = require('rupture'),
koutoSwiss = require('kouto-swiss'),
prefixer = require('autoprefixer-stylus'),
imagemin = require('gulp-imagemin'),
cp = require('child_process');
var messages = {
jekyllBuild: '<span style="color: grey">Running:</span> $ jekyll build'
};
var jekyllCommand = (/^win/.test(process.platform)) ? 'jekyll.bat' : 'jekyll';
/**
* Build the Jekyll Site
*/
gulp.task('jekyll-build', function (done) {
browserSync.notify(messages.jekyllBuild);
return cp.spawn(jekyllCommand, ['build'], {stdio: 'inherit'})
.on('close', done);
});
/**
* Wait for jekyll-build, then launch the Server
*/
gulp.task('browser-sync', gulp.series('jekyll-build'), function() {
browserSync({
server: {
baseDir: '_site'
}
});
done();
});
/**
* Stylus task
*/
gulp.task('stylus', function() {
return gulp.src('src/styl/main.styl').pipe(plumber())
.pipe(
stylus({
use: [koutoSwiss(), prefixer(), jeet(), rupture()],
compress: true,
})
)
.pipe(gulp.dest('_site/assets/css/'))
.pipe(gulp.dest('assets/css'))
.pipe(browserSync.stream());
});
ERROR SHOWN BELOW
[23:28:52] Using gulpfile ~/berserker1.github.io/gulpfile.js
[23:28:52] Starting 'default'...
[23:28:52] Starting 'browser-sync'...
[23:28:52] Starting 'jekyll-build'...
Configuration file: /home/aaryan/berserker1.github.io/_config.yml
Source: /home/aaryan/berserker1.github.io
Destination: /home/aaryan/berserker1.github.io/_site
Incremental build: disabled. Enable with --incremental
Generating...
done in 0.234 seconds.
Auto-regeneration: disabled. Use --watch to enable.
[23:28:52] Finished 'jekyll-build' after 818 ms
[23:28:52] Finished 'browser-sync' after 819 ms
[23:28:52] Starting 'stylus'...
[23:28:53] The following tasks did not complete: default, stylus
[23:28:53] Did you forget to signal async completion?
There is an issue here (whether it is the same as the one in your question we'll see if it helps):
gulp.task('browser-sync', gulp.series('jekyll-build'), function() {
browserSync({
server: {
baseDir: '_site'
}
});
done();
});
I gulp v4 task takes only two arguments - the code above has three. This should be correct:
gulp.task('browser-sync', gulp.series('jekyll-build', function(done) {
browserSync({
server: {
baseDir: '_site'
}
});
done();
}));
Plus, I added the done parameter in the first line. See if this helps.

Wait prev task before starting next tasks

I'd like to create a watcher to watch some files and compile them.
I have two tasks :
minCss
compile
I'd like to execute compile in first and wait the end before executing minCss... But it seem's not working.
My code :
var scssToCompile = [
'./public/sass/themes/adms/adms.scss',
'./public/sass/themes/arti/arti.scss',
'./public/sass/themes/avantage/avantage.scss',
'./public/sass/themes/basique/basique.scss',
'./public/sass/themes/mairie/mairie.scss',
'./public/sass/themes/vehik/vehik.scss',
'./public/sass/themes/concept/concept.scss',
'./public/sass/themes/news/news.scss',
'./public/sass/components/*.scss',
'./public/sass/_functions.scss',
'./public/sass/_settings.scss',
'./public/sass/app.scss',
'./public/sass/bottom.scss'
];
gulp.task('compile', function(){
return gulp.src(scssToCompile)
.pipe(sassGlob())
.pipe(sass({includePaths: ['./public/sass']}).on('error', function(err) {
cb(err);
}))
.pipe(gulp.dest('./public/stylesheets'));
});
gulp.task('minCss', function() {
return gulp.src('public/stylesheets/themes/**/*.css')
.pipe(minifyCss())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('public/build/css'));
});
// my watcher
gulp.task('watch', function(){
gulp.watch(scssToCompile, ['compile', 'minCss']);
});
Results :
[15:21:36] Using gulpfile C:\xampp\htdocs\gulpfile.js
[15:21:36] Starting 'watch'...
[15:21:37] Finished 'watch' after 153 ms
[15:21:41] Starting 'compile'...
[15:21:46] Starting 'minCss'...
[15:21:46] Finished 'minCss' after 6.42 μs
[15:21:48] Finished 'compile' after 6.44 s

Wrong reload order when using Gulp and browserSync

So I'm trying to compile pug (jade), javascript and sass files with Gulp V4, and using browserSync to reload the browser when any of these files change. There are a lot of guides out there, but no matter which way I write the code, it just doesn't seem to get the task order right. Im using gulp.series to set the task order, but browserSync doesn't want to play ball.
Here's a print of my Gulp file:
var gulp = require('gulp'),
... etc.
var paths = {
sass: ['src/scss/**/*.scss'],
js: ['src/js/**/*.js'],
pug: ['src/**/*.pug']
};
// Shared Tasks:
//*------------------------------------*/
gulp.task('clean', function(done){
del(['dist/assets/**/*.css', 'dist/assets/**/*.map', 'dist/assets/**/*.js']);
done();
});
// App Specific Tasks:
//*------------------------------------*/
// Sass
gulp.task('build-sass', function(){
gulp.src(paths.sass)
return sass(paths.sass, {
style: 'expanded'
})
.on('error', sass.logError)
.pipe(prefix('last 2 version', '> 1%', 'ie 8', 'ie 9'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist/assets/css'))
.pipe(cleanCSS({ advanced: false, keepSpecialComments: 0 }))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('dist/assets/css'));
});
// JS
gulp.task('build-js', function(done){
gulp.src(paths.js)
.pipe(concat('all.js'))
.pipe(gulp.dest('dist/assets/js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('dist/assets/js'))
done();
// Pug
gulp.task('build-pug', function buildHTML(done){
gulp.src(['src/**/*.pug'], {
base: 'src'
})
.pipe(pug())
.pipe(gulp.dest('./dist/'))
done();
});
// Service Tasks:
//*------------------------------------*/
// Delete the compiled views dir.
gulp.task('remove', function(done){
del(['dist/views/**/']);
done();
});
// Serve the site locally and watch for file changes
gulp.task('serve', function(done){
browserSync.init({
server: {
baseDir: './dist/',
notify: false,
open: false
}
});
// Watch & Reload Pug Files
gulp.watch([paths.pug], gulp.series('build-pug')).on('change', browserSync.reload);
// Watch & Reload Sass Files
gulp.watch([paths.sass], gulp.series('build-sass')).on('change', browserSync.reload);
});
gulp.task('default', gulp.series('clean', 'build-sass', 'build-js', 'build-pug', 'remove', 'serve', function(done){
done();
}));
And the terminal console log outputs this when starting gulp:
$ gulp
[13:09:33] Using gulpfile ~/Dropbox Aaron/Dropbox (Personal)/01_Me/01_Dev/01_My Work/*Template/gulpfile.js
[13:09:33] Starting 'default'...
[13:09:33] Starting 'clean'...
[13:09:33] Finished 'clean' after 2.64 ms
[13:09:33] Starting 'build-sass'...
[13:09:33] Finished 'build-sass' after 443 ms
[13:09:33] Starting 'build-js'...
[13:09:33] Finished 'build-js' after 4.42 ms
[13:09:33] Starting 'build-pug'...
[13:09:33] Finished 'build-pug' after 3.15 ms
[13:09:33] Starting 'remove'...
[13:09:33] Finished 'remove' after 656 μs
[13:09:33] Starting 'serve'...
[BS] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://10.130.91.51:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://10.130.91.51:3001
-------------------------------------
[BS] Serving files from: ./dist/
And this when I change a file within the watched files:
[BS] File changed: src/scss/4_elements/_elements.page.scss
[13:12:33] Starting 'build-sass'...
[13:12:34] write ./style.css
[13:12:34] Finished 'build-sass' after 366 ms
So what seems to me to be happening in this instance, the file is changing, browserSync reloads the page, and then 'build-sass' starts. Which is the wrong way round. I obviously want to build the sass, then reload the page. I have to save 2 times for the browser to refresh the code I want.
Some of the code I've used is directly from the browserSync documentation:
https://www.browsersync.io/docs/gulp#gulp-reload
This doesn't seem to work.
Your log output looks right. First it runs 'default' and then your series of tasks. Later when you modify a sass file, it starts 'build-sass'. The only problem is it doesn't reload via browserSync.reload(). So I believe the problem may be here:
gulp.watch([paths.sass], gulp.series('build-sass')).on('change', browserSync.reload);
I highly recommend
https://github.com/gulpjs/gulp/blob/4.0/docs/recipes/minimal-browsersync-setup-with-gulp4.md
that is the gulp4.0 recipe to do exactly what you are trying to do. I am using pretty much what they have there, so if you have problems getting their code to work I can help. Here is my working code:
function serve (done) {
browserSync.init({
server: {
baseDir: "./",
index: "home.html"
},
ghostMode: false
});
done();
}
function reload(done) {
browserSync.reload();
done();
}
var paths = {
styles: {
src: "./scss/*.scss",
dest: "./css"
},
scripts: {
src: "./js/*.js",
dest: "./js"
}
};
function watch() {
gulp.watch(paths.scripts.src, gulp.series(processJS, reload));
gulp.watch(paths.styles.src, gulp.series(sass2css, reload));
gulp.watch("./*.html").on("change", browserSync.reload);
}
var build = gulp.series(serve, watch);
gulp.task("sync", build);
function sass2css() {
return gulp.src("./scss/*.scss")
.pipe(cached("removing scss cached"))
// .pipe(sourcemaps.init())
.pipe(sass().on("error", sass.logError))
// .pipe(sourcemaps.write("./css/sourceMaps"))
.pipe(gulp.dest("./css"));
}
function processJS() {
return gulp.src("./js/*.js")
.pipe(sourcemaps.init())
// .pipe(concat("concat.js"))
// .pipe(gulp.dest("./concats/"))
// .pipe(rename({ suffix: ".min" }))
// .pipe(uglify())
.pipe(sourcemaps.write("./js/sourceMaps/"))
.pipe(gulp.dest("./js/maps/"));
}
Note the general use of functions instead of 'tasks' and particularly the reload(done) function. You might try simply adding that to your watch statements like
gulp.watch([paths.sass], gulp.series('build-sass', reload);
after you have added the reload function, that might be enough to fix your problem without making all the other changes as in my code. Or you might simply have to add a return statement to your 'build-sass' task so gulp knows that task has completed. Good luck.

gulp-nodemon + browserSync: has no method 'spawnSync' & long loading time

I want to run nodemon with browsersync, so that I can see changes in my code instantly. I already had a setup environment from yeoman gulp-angular so I want to avoid using liverload etc. and stick to the preset unless there is a huge reason.
I start my server with `gulp:serve'
gulp.task('serve', ['node'], function () {
browserSyncInit([
paths.tmp + '/serve',
paths.src
], [
paths.tmp + '/serve/{app,components}/**/*.css',
paths.tmp + '/serve/{app,components,node,config}/**/*.js',
paths.src + 'src/assets/images/**/*',
paths.tmp + '/serve/*.html',
paths.tmp + '/serve/{app,components}/**/*.html',
paths.src + '/{app,components}/**/*.html'
]);
});
Before browserSync is called the task node is required otherwise the routes would run into nothing:
gulp.task('node',['watch'], function(){
return nodemon({
script: paths.tmp + '/serve/server.js',
ext: 'js html',
tasks: ['browserSync'],
env: { 'NODE_ENV': 'development' } ,
nodeArgs: ['--debug=9999']
});
});
The task node starts gulp-nodemon and trigers watch to build and watch the application.
gulp.task('watch', ['templateCache', 'images_tmp', 'partials_tmp'], function () {
gulp.watch([
paths.src + '/*.html',
paths.src + '/{app,components}/**/*.scss',
paths.src + '/{app,components}/**/*.js',
paths.src + '/{app,components,node,config}/**/*.coffee',
'bower.json'
], ['templateCache', 'partials_tmp']);
});
Watch itself triggers two functions, one which inserts a scriptTag into index.html to load angularTemplateCache. And a second one which takes all html files and saves them into a templateCache.js. The second one reqires a task which copies all css & js files.
Question 1):
When I change files, it throws the error:
gulp-nodemon/index.js:76
cp.spawnSync('gulp', tasks, { stdio: [0, 1, 2] })
^
TypeError: Object #<Object> has no method 'spawnSync'
Question 2):
When I start the function, all works but it loads very long. I can speed up the loading by manually refreshing the tab which broserSync opened.
EDIT 1:
Gulp-nodemon watches the files in the directory for changes so I removed gulp-watch to exclude a source for errors. The spawnSync error stays:
gulp.task('node',['templateCache', 'images_tmp', 'partials_tmp'], function(){
return nodemon({
script: paths.tmp + '/serve/server.js',
ext: 'js html coffee scss',
tasks: ['templateCache', 'partials_tmp'],
env: { 'NODE_ENV': 'development' } ,
nodeArgs: ['--debug=9999']
}).on('restart' , function onRestart() {
console.log("################################restarted node");
//Also reload the browsers after a slight delay
setTimeout(function reload() {
browserSync.reload({
stream: false
});
}, 5000);
});
});
Edit 2:
I could solve the long loading time issue by moving the browsersync init function into the on start event of nodemon. maybe nodemon wasn't fully loaded before.
gulp.task('node',['templateCache', 'images_tmp', 'partials_tmp'], function(cb){
var called = false;
return nodemon({
script: paths.tmp + '/serve/server.js',
ext: 'js html coffee scss',
tasks: ['node'],
env: { 'NODE_ENV': 'development' } ,
nodeArgs: ['--debug=9999']
})
.on('start', function onStart() {
if (!called) {
cb();
browserSyncInit([
paths.tmp + '/serve',
paths.src
], [
paths.tmp + '/serve/{app,components}/**/*.css',
paths.tmp + '/serve/{app,components,node,config}/**/*.js',
paths.src + 'src/assets/images/**/*',
paths.tmp + '/serve/*.html',
paths.tmp + '/serve/{app,components}/**/*.html',
paths.src + '/{app,components}/**/*.html'
]);
}
called = true;
})
.on('restart' , function onRestart() {
console.log("################################restarted node");
//Also reload the browsers after a slight delay
setTimeout(function reload() {
browserSync.reload({
stream: false
});
}, 5000);
});
});
Problem is in your node.js version. In the latest update of gulp-nodemon you can see, that 0.12.x required. So if you installed new version of gulp-nodemon, on lower node.js you'll see that error.
https://github.com/JacksonGariety/gulp-nodemon/releases/tag/2.0.2
You may update node and the second way is to install previous version of gulp-nodemon.
Good luck!

Duplicate Tasks on self reloading gulp

I have set up gulp so that it will reload when the gulpfile is modified. That basic process is working, but for some reason it seems the old tasks are not being terminated properly.
var gulp = require('gulp');
var less = require('gulp-less');
var spawn = require('child_process').spawn;
gulp.task('default', function(){
var p;
if(p)
p.kill();
p = spawn('gulp', ['watch'], {stdio: 'inherit'});
});
gulp.task('watch', ['styles', 'watch-styles', 'watch-gulp']);
gulp.task('styles', function(){
return gulp.src('./**/*.less')
.pipe(less())
.pipe(gulp.dest('./'))
});
gulp.task('watch-styles', ['styles'], function(){
gulp.watch('./**/*.less', ['styles']);
});
gulp.task('watch-gulp', ['styles'], function(){
gulp.watch('./gulpfile.js', ['default']);
});
That is a basic gulpfile that demonstrates the problem. When I tweak that gulpfile to cause it to reload I receive this in the console:
[11:21:02] Starting 'default'...
[11:21:02] Finished 'default' after 5.25 ms
[11:21:02] Using gulpfile ~/repo/gulp-reload/gulpfile.js
[11:21:02] Starting 'styles'...
[11:21:02] Finished 'styles' after 34 ms
[11:21:02] Starting 'watch-styles'...
[11:21:03] Finished 'watch-styles' after 669 ms
[11:21:03] Starting 'watch-gulp'...
[11:21:03] Finished 'watch-gulp' after 1.83 ms
[11:21:03] Starting 'watch'...
[11:21:03] Finished 'watch' after 2.92 μs
Then modifying a less file within the directory gives this output
[11:21:24] Starting 'styles'...
[11:21:24] Finished 'styles' after 8.95 ms
[11:21:24] Starting 'styles'...
[11:21:24] Finished 'styles' after 2.92 ms
Each subsequent restart seems to lead to an additional call to styles, as if the old watchers are still there.
I created a small repo on Github with this example project as well.
In this task:
gulp.task('default', function(){
var p;
if(p)
p.kill();
p = spawn('gulp', ['watch'], {stdio: 'inherit'});
});
p is never defined, because you always create a new variable when you call that function. Also, you don't have a pointer to your own process which you want to kill. A safer way would be to end all the other watchers by hand:
gulp.task('watch-styles', ['styles'], function(){
var watcher = gulp.watch('./**/*.less', ['styles']);
watchers.push(watcher);
});
gulp.task('watch-gulp', ['styles'], function(){
var watcher = gulp.watch('./gulpfile.js', ['default']);
watchers.push(watcher);
watcher.on('change', function(){
watchers.forEach(function(el){
el.end();
})
})
});