Gulp LESS + autoprefix + sourcemaps frustration - gulp

I have a task like the following:
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')({ camelize: true });
gulp.task('styles-compile', function() {
return gulp.src(['less/site.less',
'less/special-*.less',
'less/editor-styles.less'])
.pipe(plugins.sourcemaps.init())
.pipe(plugins.less())
.pipe(plugins.autoprefixer('last 15 versions', 'ie 8', 'ios 6', 'android 4'))
.pipe(plugins.sourcemaps.write('.', {sourceRoot: '../less', includeContent: false}))
.pipe(gulp.dest('css'))
});
And I just seem to be unable to configure it to get sourcemaps working.
This is the closest I get to a working version - the only issue is that the generated sourcemap includes the file it is for in it's sources list - eg for site.css.map I get:
{"version":3,"sources":["site.css","../font/icon/css/fontawesome.css","site.less"...,"names":[],"mappings":"...","file":"site.css","sourceRoot":"../less"}
For one, I'm fairly sure that there is no need for the destination file itself (site.css) to appear in the sources list, but for another, it does not appear in the less directory - it is in the css directory. So when I load this up in dev tools, it is not found.
If I remove autoprefixer it all works fine, so I guess what I am seeing here is the fact that autoprefixer uses site.css for both source and destination file, so it considers there to be a mapping between them.
Based on some suggestions elsewhere, I tried adding calls to sourcemaps.write() then sourcemaps.init() in between less() and autoprefixer(), however this does not resolve the issue and, in fact adds an additional sourceMappingURL comment to the generated CSS.
Is there an accepted/better way to do this?
Based on comments from #seven-phases-max, I've changed the task up slightly:
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')({ camelize: true }),
autoprefixer = require('autoprefixer');
gulp.task('styles-compile', function() {
return gulp.src(['less/site.less',
'less/special-*.less',
'less/editor-styles.less'])
.pipe(plugins.sourcemaps.init())
.pipe(plugins.less())
.pipe(plugins.postcss([autoprefixer]))
.pipe(plugins.sourcemaps.write('.', {sourceRoot: '../less', includeContent: false}))
.pipe(gulp.dest('css'))
});
Unfortunately the output seems exactly the same, I'm still getting site.css as the first source.

Related

Gulp: minify and unminfy tasks

I am new to gulp so i don't know as much good gulp plugins. I wrote a code for minifying js, css and html using gulp and its plugins which is working fine. But now i am stuck in unminifying code. I don't know which plugins to use which can easily unminify code.
guplfile.js:
var gulp = require('gulp'),
uglify = require('gulp-uglify')
htmlmin = require('gulp-html-minifier')
csso = require('gulp-csso');
gulp.task('min_js', function () {
gulp.src('app/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('min'))
});
gulp.task('min_html', function () {
gulp.src('app/**/*.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('min'))
});
gulp.task('min_css', function () {
gulp.src('app/**/*.css')
.pipe(csso())
.pipe(gulp.dest('min'))
});
gulp.task('minify_all', ['min_js', 'min_html', 'min_css']);
//pending
//gulp.task('unminify',[]);
Uglifying/Minifying is attended for production, you should not uglify your code while you are developing (except for testing purpose).
When you start gulp tasks, you have to make sure that you have in one part your "working code", that you will transform into a "destination code".
When you are doing this :
gulp.task('min_js', function () {
gulp.src('app/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('min'))
});
The code on which you are working on is in the app folder, and your transformed code is in the min folder (it's the destination folder).
But, if the min directory is also used in development, just disable the uglify task in development (easier to debug a not-uglifyied file).
There is no need to un-minify your sources, there are still present in app folder.

Gulp watch less and error?

I am using gulp for creating some css from less and have watch function. Everything working ok when there is no errors in less files, watch is calling less function and compile css. But when i have errors in less files, watch just breaks say where is error stop. When i fix error in less file, watch does not work anymore. I have to start it again, is it possible to see if there is error and just continue watching for compiling, here is my gulp.js
// Less to CSS task
var parentPath = './content/css/';
var sourceLess = parentPath;
var targetCss = parentPath;
gulp.task('less', function () {
return gulp.src([sourceLess + 'styles.less'])
.pipe(less({ compress: true }).on('error', gutil.log))
.pipe(autoprefixer('last 10 versions', 'ie 9'))
.pipe(minifyCSS({ keepBreaks: false }))
.pipe(gulp.dest(targetCss))
.pipe(notify('Less Compiled, Prefixed and Minified'));
});
gulp.task('watch', function () {
gulp.watch([sourceLess + 'styles.less'], ['less']); // Watch all the .less files, then run the less task
});
In gulp-less plugin documentation says that it doesn't have a built-in way to fail the task and keep the watcher active. But it says that you can't do it with stream-combiner2.
You can see the example here taked from the official gulp github repo.

Gulp not watching correctly

I'm new to using gulp and I think I have it setup correctly, but it does not seem to be doing what it should be doing.
My gulpfile.js has
gulp.task('compass', function() {
return gulp.src('sites/default/themes/lsl_theme/sass/**/*.scss')
.pipe(compass({
config_file: 'sites/default/themes/lsl_theme/config.rb',
css: 'css',
sass: 'scss'
}))
.pipe(gulp.dest('./sites/default/themes/lsl_theme/css'))
.pipe(notify({
message: 'Compass task complete.'
}))
.pipe(livereload());
});
with
gulp.task('scripts', function() {
return gulp.src([
'sites/default/themes/lsl_theme/js/**/*.js'
])
.pipe(plumber())
.pipe(concat('lsl.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
// .pipe(stripDebug())
.pipe(uglify('lsl.js'))
.pipe(rename('lsl.min.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
.pipe(sourcemaps.write())
.pipe(notify({
message: 'Scripts task complete.'
}))
.pipe(filesize())
.pipe(livereload());
});
and the watch function
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./sites/default/themes/lsl_theme/js/**/*.js', ['scripts']);
gulp.watch('./sites/default/themes/lsl_theme/sass/**/*.scss', ['compass']);
});
when I run gulp, the result is
[16:14:36] Starting 'compass'...
[16:14:36] Starting 'scripts'...
[16:14:36] Starting 'watch'...
[16:14:37] Finished 'watch' after 89 ms
and no changes are registered.
for file structure, my gulpfile.js is in the root directory and the sass, css, and js are all in root/sites/default/themes/lsl_theme with the sass folder containing the folder 'components' full of partials.
My assumption is that you are on windows? Correct me if I'm wrong.
There is this problem that gulp-notify tends to break the gulp.watch functions. Try commenting out
// .pipe(notify({
// message: 'Scripts task complete.'
// }))
and see if the problem still exists.
If that does fix the issue, a solution from this thread may be helpful.
You can use the gulp-if
plugin in combination with
the os node module
to determine if you are on Windows, then exclude gulp-notify, like
so:
var _if = require('gulp-if');
//...
// From https://stackoverflow.com/questions/8683895/variable-to-detect-operating-system-in-node-scripts
var isWindows = /^win/.test(require('os').platform());
//...
// use like so:
.pipe(_if(!isWindows, notify('Coffeescript compile successful')))
It turns out that a large part of my issue was just simply being a rookie with Gulp. When I removed 'scripts' from my gulp watch it started working.
I then made the connection that it was watching the same directory that it was placing the new concatenated and minified js files in so it was putting the new file, checking that file, and looping over and over causing memory issues as well as not allowing 'compass' to run.
After creating a 'dest' folder to hold the new js everything started working just peachy.

How can I use gulp-imagemin to replace the original file

I need to setup a gulp task to optimize the image files in a directory, but since this is an existing site, I cannot change the output directory. In other words, I need the optimized image to replace the existing image.
I have googled around, and read the documentation for gulp-imagemin, and even tried to do it using the shell, to no avail.
There must be a way to do this, but so far, I have found no evidence of how to do so on the internet. I'm hoping the good people of SO can help me out in this regard :)
Here's my code:
var gulp = require('gulp');
var imagemin = require('gulp-imagemin');
var pngcrush = require('imagemin-pngcrush');
var paths = {
files: './webroot/sites/files/**',
filesDest: './webroot/sites/files',
};
gulp.task('files', function() {
'use strict';
// Minify all images
return gulp.src(paths.files, {base: './webroot/sites/files'})
.pipe(imagemin({
progressive: true,
svgoPlugins: [{removeViewBox: false}],
use: [pngcrush()]
}))
.pipe(gulp.dest(paths.filesDest));
});
gulp.task('default', ['files']);
This code, as Delapouite said, is working, I was simply checking for it incorrectly.

Why don't newly added files trigger my gulp-watch task?

I have a gulp task which uses gulp-imagemin to compress images. When I add new files to this directory I'd like for this task to compress them as well. I read that gulp.watch doesn't trigger on new files and that I should try gulp-watch so I used it like so;
gulp.task('images', function() {
watch({glob: './source/images/*'}, function (files) {
return files
.pipe(plumber())
.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
});
This works the same as gulp.watch on the first run, but when I add a new image to the directory nothing happens. If I overwrite an existing file however, it DOES run the task again, so it does behave differently.
The documentation on gulp-watch called this "Batch Mode" and said I could also run the task on a per-file basis, so I tried this way too;
gulp.task('images', function() {
gulp.src('./source/images/*')
.pipe(watch())
.pipe(plumber())
.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
But nothing changed. Why isn't adding files to my image directory triggering the task?
Adding an extra argument {cwd:'./'} in gulp.watch worked for me:
gulp.watch('src/js/**/*.js',{cwd:'./'},['scripts']);
2 things to get this working:
1 Avoid ./ in the file/folder patterns
2 Ensure ./ in the value for cwd
Good Luck.
Ref:- https://stackoverflow.com/a/34346524/4742733
Most likely such kind of questions are redirected to gaze package and its internal processes, that runs complicated watching procedures on your OS. In this case you should pass images/**/* to glob option, so gaze will watch all (including new) files in images directory:
var gulp = require('gulp');
var watch = require('gulp-watch');
var imagemin = require('gulp-imagemin');
gulp.task('default', function() {
watch({glob: 'images/**/*'}, function (files) {
files.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
});
But this fill not fix case, when you have empty images directory. If you want to watch them, pass ['images', 'images/**/*'] to glob, and it will watch directory, that initially empty.
P.s. also you dont need gulp-plumber in this case, because watch will rerun function, that uses imagemin every time, even when imagemin pops an error.