I have 2 tasks:
whitelabel - I have a gulp task that copies a given whitelabel project into a folder
sass - compile the sass project within that folder
My problem is that when I put them to run in sequence on my default task the css the files are copied but the sass task doesnt generated the css it is suposed to. But, if i run one task than the other the css file is generated.
What am I missing?
Whitelabel Task
gulp.task('whitelabel', function() {
var argv = yargs.argv;
if (argv.whitelabel){
gulp.src('./whitelabels/_template/**/*')
.pipe(gulp.dest('./assets'));
return gulp.src('./whitelabels/'+ argv.whitelabel +'/**/*')
.pipe(gulp.dest('.'));
} else {
return gulp.src('./whitelabels/_template/**/*')
.pipe(del.sync(['./assets/']))
.pipe(gulp.dest('.'));
}
});
SASS Task
gulp.task('sass', function() {
return gulp.src('assets/styles/style.scss')
.pipe($.sourcemaps.init())
.pipe($.sass({
style: 'expanded'
}))
.on('error', $.notify.onError({
title: 'SASS Failed',
message: 'Error(s) occurred during compile!'
}))
.pipe($.sourcemaps.write())
.pipe(gulp.dest('assets/styles'))
.pipe(reload({
stream: true
}))
.pipe($.notify({
message: 'Styles task complete'
}));
});
Default Task
gulp.task('default', ['config', 'browser-sync', 'whitelabel', 'sass', 'minify-css'], function() {
gulp.watch('whitelabels/_template/assets/styles/*.css', function(file) {
if (file.type === "changed") {
reload(file.path);
}
});
gulp.watch(['*.html', 'app/**/*.html', 'views/*.html'], ['bs-reload']);
gulp.watch(['whitelabels/_template/assets/js/*.js'], ['whitelabel','bs-reload']);
gulp.watch(['app/*.js'], ['bs-reload']);
gulp.watch('whitelabels/_template/assets/styles/**/*.scss', ['whitelabel', 'sass', 'minify-css']);
});
Your original default task does not guarantee that the tasks are run in any specific order - in fact they run in parallel.
Many people use run-sequence https://www.npmjs.com/package/run-sequence to run tasks in a specified order.
Or you could make the 'whitelabel' task a dependency of the sass task by
gulp.task('sass', ['whitelabel'], function() {
Related
I'm trying to convert my gulp 3 file to gulp 4 after upgrading to Node v12, and I'm still erroring out even after reading tutorials/examples. I'm getting the AssertionError [ERR_ASSERTION]: Task never defined: sass error
My gulpfile.js file:
const gulp = require('gulp');
const browserSync = require('browser-sync').create();
const sass = require('gulp-sass');
// Compile Sass & Inject Into Browser
gulp.task('sass', gulp.series('sass'), function() {
return gulp.src(['node_modules/bootstrap/scss/bootstrap.scss', 'src/scss/*.scss'])
.pipe(sass())
.pipe(gulp.dest("src/css"))
.pipe(browserSync.stream());
});
// Move JS Files to src/js
gulp.task('js', gulp.series(['js']), function() {
return gulp.src(['node_modules/bootstrap/dist/js/bootstrap.min.js', 'node_modules/jquery/dist/jquery.min.js','node_modules/popper.js/dist/umd/popper.min.js'])
.pipe(gulp.dest("src/js"))
.pipe(browserSync.stream());
});
// Watch Sass & Serve
gulp.task('serve', gulp.series(['sass']), function() {
browserSync.init({
server: "./src"
});
gulp.watch(['node_modules/bootstrap/scss/bootstrap.scss', 'src/scss/*.scss'], gulp.series('sass'));
gulp.watch("src/*.html").on('change', browserSync.reload);
});
// Move Fonts to src/fonts
gulp.task('fonts', gulp.series(['fonts']), function() {
return gulp.src('node_modules/font-awesome/fonts/*')
.pipe(gulp.dest('src/fonts'))
})
// Move Font Awesome CSS to src/css
gulp.task('fa', gulp.series(['fa']), function() {
return gulp.src('node_modules/font-awesome/css/font-awesome.min.css')
.pipe(gulp.dest('src/css'))
})
gulp.task('default', ['js','serve', 'fa', 'fonts']);
Any help is greatly appreciated, thanks!
To start this form is incorrect:
gulp.task('sass', gulp.series('sass'), function() {
That calls the 'sass' at the beginning of the 'sass' task itself. It would presumably cause an infinite loop. I suspect it is the cause of your error because you are calling the 'sass' task before it has been completely defined.
gulp.task takes only two arguments: the name and one function, so this is correct:
gulp.task('sass', function() {
so make that change to all your tasks except:
gulp.task('serve', gulp.series(['sass']), function() {
where you might want to run the 'sass' task before starting the server. But you can still only have two arguments to gulp.task so try
gulp.task('serve', gulp.series('sass', function() {
Finally, this line
gulp.task('default', ['js','serve', 'fa', 'fonts']);
needs a gulp.series to work properly in gulp v4 so try
gulp.task('default', gulp.series('js','serve', 'fa', 'fonts'));
Once you make all those changes, see if you get any other errors.
Today I migrated to Gulp 4, but I'm not able to get my watch function to work.
// Watch
gulp.task('watch', gulp.series('typescript', 'sass', 'browserSync', function(){
gulp.watch('./app/styles/**/*.scss', gulp.series('sass'));
gulp.watch('app/scripts/**/*.ts', gulp.series('typescript'));
gulp.watch('./app/*.html', browserSync.reload);
}));
typescript, sass, browserSync will run but watch does not react to file changes.
I just had the same problem. You don't actually have a reference to the initialized browserSync inside your watch gulp task. Instead of having your browserSync.init function in a separate browserSync gulp task, move it to inside your watch task, and it should work. Hope this helps!
Example:
gulp.task('watch', gulp.series(function (){
browserSync.init({
proxy:"http://localhost:8888",
injectChanges: true,
plugins: ["bs-html-injector?files[]=*.html"]
});
var html = gulp.watch('development/index.html');
html.on('change', function(path, stats) {
console.log('you changed the html');
browserSync.notify("Compiling, please wait!");
browserSync.reload("index.html");
})
var js = gulp.watch('development/**/*.js');
js.on('change', function(path, stats) {
console.log('you changed the js');
browserSync.notify("Compiling, please wait!");
browserSync.reload();
})
var css = gulp.watch('development/**/*.css');
css.on('change', function(path, stats) {
console.log('you changed the css');
browserSync.notify("Injecting CSS!");
browserSync.reload("*.css");
})
}));
Change gulp.watch('app/scripts/**/*.ts', gulp.series('typescript')); to a absolute gulp.watch('./app/scripts/**/*.ts', gulp.series('typescript'));
Also i normally stick this syntax, per task.
var watcher = gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify'));
watcher.on('change', function(path, stats) {
console.log('File ' + path + ' was changed');
});
I had some issues too, and i found this tutorial of gulp 4, this is my gulpfile to compile scss and watch the Scss files, concat and compile to a main.min.css with autoprefix.
var gulp = require('gulp'),
concat = require('gulp-concat'),
autoprefixer = require('gulp-autoprefixer'),
sass = require('gulp-sass');
//task para o sass
var paths = {
styles: {
src: 'scss/**/*.scss',
dest: 'css'
}
};
function styles() {
return gulp
.src(paths.styles.src, {
sourcemaps: true
})
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
.pipe(concat('main.min.css'))
.pipe(autoprefixer({
browser: ['last 2 version', '> 5%'],
cascade: false
}))
.pipe(gulp.dest(paths.styles.dest));
}
function watch() {
gulp.watch(paths.styles.src, styles);
}
var build = gulp.parallel(styles, watch);
gulp.task(build);
gulp.task('default', build);
I think that on the gulp v4 you need to use the gulp.parallel. I'm digging to learn more about the new version.
The concatenation and destination to my public/assets/css is only working if i run 2 times the task. Even if I run just the app.css (npm run dev app.css), only work if I run twice.
const gulp = require('gulp')
const htmlmin = require('gulp-htmlmin')
const uglify = require('gulp-uglify')
const uglifycss = require('gulp-uglifycss')
const concat = require('gulp-concat')
const babel = require('gulp-babel')
const sass = require('gulp-sass')
gulp.task('app', ['app.html', 'app.sass', 'app.js', 'app.assets', 'app.css'])
gulp.task('app.html', function(){
gulp.src(['app/**/*.html'])
.pipe(htmlmin({ collapseWhitespace: true, removeComments: true}))
.pipe(gulp.dest('public'))
})
gulp.task('app.sass', function () {
gulp.src(['sass/main.scss'])
.pipe(sass.sync().on('error', sass.logError))
.pipe(gulp.dest('app/css'))
});
gulp.task('app.css', function(){
gulp.src(['app/**/*.css'])
.pipe(uglifycss({ "uglyComments": true}))
.pipe(concat('app.min.css'))
.pipe(gulp.dest('public/assets/css'))
})
gulp.task('app.js', function(){
gulp.src(['app/**/*.js'])
.pipe(babel({ presets: ['es2015'] }))
.pipe(uglify())
.pipe(concat('app.min.js'))
.pipe(gulp.dest('public/assets/js'))
})
gulp.task('app.assets', function(){
gulp.src(['assets/**/*.*'])
.pipe(gulp.dest('public/assets'))
})
For gulp to respect the order of the task dependencies you defined, you need to tell it when the task is done.
To do so, you need to return a stream, a promise, or call the task function callback parameter.
Since your tasks are pretty basic, just returning the stream should be enough.
gulp.task('app.sass', function () {
return gulp.src(['sass/main.scss']) // notice the return here
.pipe(sass.sync().on('error', sass.logError))
.pipe(gulp.dest('app/css'));
});
// make the sass task a dependency of the CSS task
gulp.task('app.css', ['app.sass'], function(){
return gulp.src(['app/**/*.css']) // notice the return here
.pipe(uglifycss({ "uglyComments": true}))
.pipe(concat('app.min.css'))
.pipe(gulp.dest('public/assets/css'));
});
Now you don't need the app.sass since it will run before app.css.
gulp.task('app', ['app.html', 'app.js', 'app.assets', 'app.css'])
I think that your tasks should be waiting for a result from the previous task. You can't just run several tasks in one time.
Try with gulp-sequence plugin. Install gulp-sequence and add the following line on the top of your gulpfile.js:
const gulpSequence = require('gulp-sequence')
Replace your current 'app' task by:
gulp.task('app', gulpSequence('app.html', 'app.sass', 'app.js', 'app.assets', 'app.css'))
I've been trying to improve my standard gulpfile to notify when errors occur when compiling scss and JS.
SCSS Issue
I have it working for SCSS, it throws the error in terminal, makes a noise and doesn't stop gulp running - which is great.
Strangely, my styles used to compile when I ran gulp, but now I need to save one of the .scss files to start gulp (again this is good, but I want it to compile on running gulp).
gulp
[12:07:06] Using gulpfile ~PATH/gulpfile.js
[12:07:06] Starting 'scripts'...
[12:07:06] Starting 'watch'...
[12:07:06] Finished 'watch' after 32 ms
[12:07:07] PATH/js/script-dist.js reloaded.
[12:07:07] Finished 'scripts' after 455 ms
[12:07:07] Starting 'default'...
[12:07:07] Finished 'default' after 15 μs
JS Issue
I'm also trying to notify of errors and exactly where they're coming from in for the JS too (and also prevent gulp from stopping when an error occurs). Tried adding gulp-jshint, but it doesn't seem to be working. It flags the error with a noise etc... but doesn't tell me which of the concatenated files the error is located in. It just says:
Error in plugin 'gulp-uglify'
Message:
[_PATH_]/js/script-dist.js: Unexpected token keyword «var», expected punc «{»
Details:
fileName: [_PATH_]/js/script-dist.js
lineNumber: 3
Here is my gulpfile.js
var gulp = require('gulp');
// --------------------------------------------------------------
// Plugins
// ---------------------------------------------------------------
var concat = require('gulp-concat');
var stripDebug = require('gulp-strip-debug');
var uglify = require('gulp-uglify');
var jshint = require('gulp-jshint');
var include = require('gulp-include');
var sass = require('gulp-sass');
var minifycss = require('gulp-minify-css');
var watch = require('gulp-watch');
var livereload = require('gulp-livereload');
var notify = require('gulp-notify');
var plumber = require('gulp-plumber');
// --------------------------------------------------------------
// JS
// ---------------------------------------------------------------
gulp.task('scripts', function() {
return gulp.src(['./js/script.js'])
.pipe(include())
.pipe(plumber({errorHandler: errorScripts}))
.pipe(concat('script-dist.js'))
//.pipe(stripDebug())
.pipe(jshint())
.pipe(uglify())
.pipe(gulp.dest('./js/'))
.pipe(livereload());
});
// --------------------------------------------------------------
// Styles
// ---------------------------------------------------------------
gulp.task("styles", function(){
return gulp.src("./ui/scss/styles.scss")
.pipe(include())
.pipe(plumber({errorHandler: errorStyles}))
.pipe(sass({style: "compressed", noCache: true}))
.pipe(minifycss())
.pipe(gulp.dest("./ui/css/"))
.pipe(livereload());
});
// --------------------------------------------------------------
// Errors
// ---------------------------------------------------------------
// Styles
function errorStyles(error){
notify.onError({title: "SCSS Error", message: "Check your terminal", sound: "Sosumi"})(error); //Error Notification
console.log(error.toString()); //Prints Error to Console
this.emit("end"); //End function
};
// Scripts
function errorScripts(error){
notify.onError({title: "JS Error", message: "Check your terminal", sound: "Sosumi"})(error); //Error Notification
console.log(error.toString()); //Prints Error to Console
this.emit("end"); //End function
};
// --------------------------------------------------------------
// Watch & Reload
// ---------------------------------------------------------------
gulp.task('watch', function() {
gulp.watch('./ui/scss/*.scss', ['styles']);
gulp.watch(['./js/*.js', '!./js/script-dist.js'], ['scripts']);
});
gulp.task('default', ['styles', 'watch']);
gulp.task('default', ['scripts', 'watch']);
livereload.listen();
(My JS isn't great, so please bear with me )
Update
I've now managed to plumb a JS error through to terminal, but not sure how to report what the error actually is, which file the error is coming from and which line? Obviously need to replace the console.log with some variables but not sure how to achieve this?
gulp.task('scripts', function() {
return gulp.src(['./js/script.js'])
.pipe(include())
.pipe(plumber(
//{errorHandler: errorScripts};
function() {
console.log('There was an issue compiling scripts');
this.emit('end');
}
))
.pipe(concat('script-dist.js'))
//.pipe(stripDebug())
//.pipe(jshint())
.pipe(uglify())
.pipe(gulp.dest('./js/'))
.pipe(livereload());
});
Styles not running answer:
When running you default task, your styles are not compiled, because you do this:
gulp.task('default', ['styles', 'watch']);
gulp.task('default', ['scripts', 'watch']);
Basically what you're doing here is overwriting your default task with a new one.
This can be overcome easily by combining the two:
gulp.task('default', ['scripts', 'styles', 'watch']);
Error notification in console answer:
You should do the jshinting before concatenation, or else you will get error reporing on the concatenated file (script-dist.js).
You should change your gulpfile to:
gulp.task('scripts', function() {
return gulp.src(['./js/script.js'])
.pipe(include())
.pipe(plumber(
//{errorHandler: errorScripts};
function() {
console.log('There was an issue compiling scripts');
this.emit('end');
}
))
.pipe(jshint())
.pipe(concat('script-dist.js'))
.pipe(stripDebug())
.pipe(uglify())
.pipe(gulp.dest('./js/'))
.pipe(livereload());
});
That should do the trick ;-)
How can I tell Gulp to run a task first before another?
For instance, I need to crunch .less file into a .css first,
// Crunch less into css.
gulp.task('less', function () {
return gulp.src([
'css/myless.less'
])
.pipe(less().on('error', function (err) {
console.log(err);
}))
.pipe(cssmin().on('error', function(err) {
console.log(err);
}))
.pipe(rename({suffix: '.less'}))
.pipe(gulp.dest('css/'));
});
Then concat it with other normal .css files,
var concat = require('gulp-concat'),
minifyCSS = require('gulp-minify-css'),
clean = require('gulp-clean');
// CSS concat, auto-prefix and minify
gulp.task('styles', function() {
gulp.src([
'css/myless.less.css',
'css/normal.css'
])
.pipe(concat('main.css'))
.pipe(minifyCSS())
.pipe(gulp.dest('css/'));
});
Run task,
gulp.task('default', ['less', 'styles'], function() {
})
It only optimise 'css/normal.css', but not does not concat it with 'css/myless.less.css'.
What should I do?
Your styles task should depend on the less one to wait for its completion. Doing what you did will run the two tasks in parallel.
You can specify an array of dependent task on each task of your gulpfile:
gulp.task('styles', ['less'], function () {
Then your defaulttask should look like this:
gulp.task('default', ['styles']);