Do not minify already minified files during concatenation and minification - gulp

I have a gulp task which minifies CSS files and concatenates them to one file:
gulp.task('minify-css', function() {
'use strict';
var pathsToMinifyAndConcat = [
'css/index.css'
];
var pathsToConcatOnly = [
'lib/css/font-awesome-4.3.0/font-awesome.min.css'
];
var minifyFiles = require('gulp-cssnano');
var concatAllFilesToOneFile = require('gulp-concat');
return gulp.src(
[]
.concat(pathsToMinifyAndConcat)
.concat(pathsToConcatOnly)
)
.pipe(minifyFiles())
.pipe(concatAllFilesToOneFile('application.min.css'))
.pipe(gulp.dest('dist'));
});
But, if some files are already minified (like font-awesome.min.css for example), it should not be minified again - it should be only concatenated, and it should be omitted from the minifying process. Is there a way to do it without hacky solutions (I don't want to use solutions which I can't fully understand - and I'm pretty new to gulp) with preserved files order? I found a plugin to add src files in any point in the pipeline: gulp-add-src, but it seems to be inactive for a while.

There is more than one way of doing what you want. I will give you two examples.
First:
var gulp = require('gulp');
var minify = require('gulp-cssnano');
var concat = require('gulp-concat');
var merge = require('merge-stream');
gulp.task('minify-css', function() {
var pathsToMinify = [
'css/style1.css'
];
var pathsToConcat = [
'css/style2.css'
];
var minStream = gulp.src(pathsToMinify)
.pipe(minify());
var concatStream = gulp.src(pathsToConcat)
return merge(minStream, concatStream)
.pipe(concat('all.css'))
.pipe(gulp.dest('dist'));
});
In this example it is created two different streams. One is minified and the other is not. In the end these two streams are merged, concatenated and then the files are written in the disk.
Second:
var gulp = require('gulp');
var minify = require('gulp-cssnano');
var concat = require('gulp-concat');
var gulpFilter = require('gulp-filter');
gulp.task('minify-css', function() {
var paths = [
'css/style1.css',
'css/style2.css'
];
// Files to minify.
var filter = gulpFilter([
'style1.css'
],
{
restore: true
});
return gulp.src(paths)
.pipe(filter)
.pipe(minify())
.pipe(filter.restore)
.pipe(concat('all.css'))
.pipe(gulp.dest('dist'));
});
In this example, just one stream is created but the vinyl file objects are filtered by gulp-filter and just the filtered ones are minified. Then, all the files originally in the pipeline are restored with filter.restore and concatenated.
There are other possibilities, like creating two different tasks where one just minifies and the other concatenates, but with this approach you would need to write the minified files temporarily in the disk.

Late to the party, as usual, but another option would be to conditionally minify files using gulp-if. Something like this should work:
const gulp = require('gulp'),
gulpif = require('gulp-if'),
concat = require('gulp-concat'),
minifyCss = require('gulp-cssnano');
gulp.task('css', function () {
gulp.src([
'css/index.css',
'lib/css/font-awesome-4.3.0/font-awesome.min.css'
])
.pipe(gulpif(file => !(file.path.includes('.min.css')), minifyCss()))
.pipe(concat('app.min.css'))
.pipe(gulp.dest('dist'));
});
Hope this helps!

Related

postcss/precss - convert .scss to .css

I'm usign postcss/precss with gulp to convert my scss markup to valid css. This is my gulpfile.js:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var precss = require('precss');
var watch = require('gulp-watch');
gulp.task('stream', function () {
var processors = [
precss
];
return watch('src/*.css', { ignoreInitial: false })
.pipe(postcss(processors))
.pipe(gulp.dest('dest'));
});
gulp.task('default', gulp.parallel('stream'));
The problem is that it doesn't change file extensions, so I need to write scss in *.css files, and what I am trying to do is to set it to read scss from *.scss files and output css into *.css files. Can anybody tell me how to achieve that?
Not an expert on this, so I'll just share how we do sass compilation.
We use gulp-concat to concat the files together into one .css file. Your gulp snippet would be as follows:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var precss = require('precss');
var watch = require('gulp-watch');
var concat = require('gulp-concat');
gulp.task('stream', function () {
var processors = [
precss
];
return watch('src/*.css', { ignoreInitial: false })
.pipe(postcss(processors))
.pipe(concat('FILENAME.css'))
.pipe(gulp.dest('dest'));
});
gulp.task('default', gulp.parallel('stream'));
Don't forget to do npm install --save-dev gulp-concat first!

gulp-concat is adding same files twice

I'm seeing a similar issue as this post (gulp-concat twice the content).
However, I'm dumping the concatenated file into a different directory, so it's not pulling in the resulting concatenated file into task, yet I'm seeing the contents of each file doubling up for some reason.
My gulp file is as follows:
/* jshint node: true */
module.exports = function (gulp, options, plugins) {
var merge = require('merge-stream');
var uglify = require('gulp-uglify');
var pump = require('pump');
var gp_concat = require('gulp-concat');
var gp_rename = require('gulp-rename');
var gp_ignore = require('gulp-ignore');
var ngAnnotate = require('gulp-ng-annotate');
var paths = require('../paths');
var utils = require('../utils');
var base = [
paths.APP,
paths.ETC,
paths.DESIGN
];
gulp.task('scripts:clean', function () {
var srcOptions = {
read: false
};
var tasks = base.map(function (folder) {
return gulp.src(folder + '/**/' + paths.GENERATED_SUBPATH + '/js/**/*.js', srcOptions)
.pipe(plugins.clean({force: true}));
});
return merge(tasks);
});
gulp.task('compress', function () {
var filesToInclude = ['**/app/components/**/*.js'
];
var excludeCondition = '**/*.spec*.js'
var fileToDest = paths.GLOBAL + '/'+paths.GENERATED_SUBPATH + '/js';
return gulp.src(filesToInclude)
.pipe(gp_ignore.exclude(excludeCondition))
.pipe(ngAnnotate({add: true}))
.pipe(gp_concat('all.concat.js'))
.pipe(gulp.dest('dist'))
.pipe(gp_rename('all.min.js'))
.pipe(uglify())
.pipe(gulp.dest(fileToDest));
});
gulp.task('scripts:build', ['scripts:clean', 'compress']);
};
Can someone help me understand why the
var filesToInclude = ['**/app/components/**/*.js];
would bring in each file twice? I've checked the files and no, the files are not duplicated anywhere in there.
It seems that the issue was with the definition of the filesToInclude, with it starting out with a wildcard. Since the fileToDest puts the file in a separate target directory, but the structure is the same, the process picks up the files twice.

Remove all min.css files from directory with Gulp

I am completely new to gulp, and while I have managed to implement some cool tasks wit gulp, I am having trouble implementing a task that will clear files matching specic pattern from specified directory.
In this particular case I would like to remove all files matching pattern '*.min.css' from css dir.
Here is a piece of code that deletes all files including directory, which is wrong. I want to remove only min.css files
var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify"),
sass = require('gulp-sass'),
rename = require('gulp-rename'),
del = require('del');
var paths = {
webroot: "./wwwroot/"
};
paths.cssMinOutputPath = paths.webroot + "css";
gulp.task("clean:min.css", function (cb) {
del([paths.cssMinOutputPath, "*.min.css"], cb);
});
I was keep playing around, and magically I have resolved the issue. It makes sense though. Here is the snippet:
gulp.task("clean:min.css", function (cb) {
del([paths.cssMinOutputPath + "/*.min.css"], cb);
});

Gulp Browserify with glob and uglify/factor-bundle

I'm currently getting into browserify. I like it so far but before I start using it I want to automate it. Gulp is the build system of my choice.
So what I actually want to do is:
Get js/app/**.js, bundle it to js/bundle/ and extract common dependencies into js/bundle/common.js. In addition uglify everything and add source maps.
Well. The gulp support for browserify kinda seems poor, at least my google researches were pretty disappointing.
Anyway. What I've got so far.
var gulp = require('gulp'),
browserify = require('browserify'),
factor = require('factor-bundle');
// ...
// gulp task
return browserify({
entries: ['js/app/page1.js', 'js/app/page2.js'],
debug: true
})
.plugin(factor, {
o: ['js/bundle/page1.js', 'js/bundle/page2.js']
})
.bundle()
.pipe(source('common.js'))
.pipe(gulp.dest('js/bundle/'));
Well this is neither uglifying nor adding sourcemaps and much less using a glob pattern. I can find an official recipe which shows me how to use the pipe to add additional transformations like uglify. But it's only for a single file.
as an outputs parameter to factor-bundle, use streams instead of file paths. You can do whatever you want with the streams then.
var indexStream = source("index.js");
var testStream = source("tests.js");
var commonStream = bundler.plugin('factor-bundle', { outputs: [indexStream, testStream] })
.bundle()
.pipe(source('common.js'));
return merge(indexStream, commonStream, testStream)
.pipe(buffer())
.pipe(sourcemaps.init({ debug: true, loadMaps: true }))
.pipe(uglify())
.pipe(gulp.dest('js/bundle/'))
Thanks to Liero's answer, I got something very similar working. Here's the complete gulpfile:
const gulp = require('gulp');
const browserify = require('browserify');
const factor = require('factor-bundle');
const source = require('vinyl-source-stream');
const sourcemaps = require('gulp-sourcemaps');
const buffer = require('gulp-buffer');
const merge = require('gulp-merge');
gulp.task('bfb', function () {
const fejs = 'public/javascripts/' // location of source JS
const fejsb = fejs + 'b/'; // location of bundles
const modules = [ // aka entry points
'accounts',
'invoice',
'invoices',
// etc...
];
const inputs = [];
const streams = [];
modules.forEach(function (module) {
inputs.push(fejs + module + '.js');
streams.push(source(module + '.js'));
});
const bundler = browserify(inputs, {});
const commonStream = bundler.plugin(factor, { outputs: streams })
.bundle()
.pipe(source('common.js'));
streams.push(commonStream);
return merge(streams)
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
//.pipe(uglify()) // haven't tested this bit
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(fejsb));
});

Gulp: how to watch multiple files and perform a task for only the changes files?

I wanna do this thing:
I have a folder with many js files. When I save one of them, I want to save the minified file in other folder.
I got it partially, because my script watch many files and when I change one, all files are copied and minified to the destination folder.
I discover recently that gulp.run is not used anymore.
If someone could help me, I'll be greatful.
I was trying this way:
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var watch = require('gulp-watch');
var files_dev = "./_sys/js/private/*.js";
var path_prod = "./_sys/js/public/";
gulp.task('dist-file', function(file) {
gulp.src(file)
.pipe(uglify())
.pipe(gulp.dest(path_prod));
});
gulp.task('default', function() {
gulp.watch(files_dev).on("change", function(file) {
gulp.run('dist-file');
});
dist-file doen't need to be a gulp task, you can make that a function which you can pass the file or glob to process. Also watch is part of gulp now so you shouldn't need gulp-watch.
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var files_dev = "./_sys/js/private/*.js";
var path_prod = "./_sys/js/public/";
function uglifyFile (file) {
gulp.src([file])
.pipe(uglify())
.pipe(gulp.dest(path_prod));
}
gulp.task('watch-test', function() {
gulp.watch(files_dev).on("change", function (event) {
uglifyFile(event.path);
});
});