gulp-concat is adding same files twice - gulp

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.

Related

Not getting 'gulp-version-number' to work

First time looking at gulp and having the project land on my lap, and of-course not getting it to work.
I need to get a version number on the files and not getting 'gulp-version-number' to work - the old code does, it just "jumps over" the versionNumber command.
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sourcemaps = require('gulp-sourcemaps');
var minifycss = require('gulp-minify-css');
var versionNumber = require('gulp-version-number');
var jsDest = 'ui/dist/js/';
var versionConfig = {
value: '%MDS%',
append: {
key: 'v',
to: ['css', 'js']
},
output: {
file: 'version.json'
}
};
gulp.task('scripts', function () {
return gulp.src('ui/js/site/*.js')
.pipe(concat('site.js'))
.pipe(gulp.dest(jsDest))
.pipe(rename('site.min.js'))
.pipe(versionNumber(versionConfig)) //<-- not doing notin'
.pipe(uglify())
.pipe(gulp.dest(jsDest));
});
//and the same for SASS/CSS
Environment is Visual Studio 2015.
Glad for any input!
(Next step is to modify the references to the files with version nbr...)

gulp-replace if content of files match regex

I have a folder of HTML files that contain a comment at the top with metadata. I would like to run one gulp-replace operation if the metadata matches one regex, and another gulp-replace operation if it doesn't match, then continue on with the rest of the tasks pipeline. If tried various iterations using gulp-if but it always results in "TypeError: undefined is not a function" errors
import gulp from 'gulp';
import plugins from 'gulp-load-plugins';
const $ = plugins();
function preprocess() {
var template_data = new RegExp('<!-- template_language:(\\w+)? -->\n', 'i');
var handlebars = new RegExp('<!-- template_language:handlebars -->', 'i');
var primaryColor = new RegExp('#dc002d', 'gi');
var mailchimpColorTag = '*|PRIMARY_COLOR|*';
var handlebarsColorTag = '{{PRIMARY_COLOR}}';
var replaceCondition = function (file) {
return file.contents.toString().match(handlebars);
}
return gulp.src('dist/**/*.html')
.pipe($.if(
replaceCondition,
$.replace(primaryColor, handlebarsColorTag),
$.replace(primaryColor, mailchimpColorTag)
))
.pipe($.replace, template_data, '')
.pipe(gulp.dest('dist'));
}
What's the most efficient way to go about this?
gulp-filter was the answer. Whereas gulp-if can be used to decide whether a particular operation should be applied to the whole stream, gulp-filter can be used to decide which files in a stream an operation should be applied to.
import gulp from 'gulp';
import plugins from 'gulp-load-plugins';
const $ = plugins();
function preprocess() {
var template_language = new RegExp('<!-- template_language:(\\w+)? -->\n', 'i');
var handlebars = 'handlebars';
var primaryColor = new RegExp('#dc002d', 'gi');
var handlebarsColorTag = '{{PRIMARY_COLOR}}';
var handlebarsCondition = function (file) {
var match = file.contents.toString().match(template_language);
return (match && match[1] == handlebars);
}
var handlebarsFilter = $.filter(handlebarsCondition, {restore: true});
var mailchimpColorTag = '*|PRIMARY_COLOR|*';
var mailchimpCondition = function (file) {
return !handlebarsCondition(file);
}
var mailchimpFilter = $.filter(mailchimpCondition, {restore: true});
return gulp.src('dist/**/*.html')
.pipe(handlebarsFilter)
.pipe($.replace(primaryColor, handlebarsColorTag))
.pipe($.debug({title: 'Applying ' + handlebarsColorTag}))
.pipe(handlebarsFilter.restore)
.pipe(mailchimpFilter)
.pipe($.replace(primaryColor, mailchimpColorTag))
.pipe($.debug({title: 'Applying ' + mailchimpColorTag}))
.pipe(mailchimpFilter.restore)
.pipe($.replace(template_language, ''))
.pipe(gulp.dest('dist'));
}

Do not minify already minified files during concatenation and minification

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!

How to concat multiple jQuery files into one using Gulp?

I'm wanting to only load one JS file which uses jQuery code, but am confused about how to best do it. The thing I'm worried about is doing something sloppy like the below to solve the issue of loading all the scripts under $(document).ready(function(){});
gulp.task('compile-js', function() {
gulp.src(['./js/initialization.js', './stuff.js'./js/end.js'])
.pipe(concat('script.js'))
.pipe(gulp.dest('./public/javascripts/'));
});
where initialization.js and end.js are for the wrapping of the document.ready function (I know lol, hence asking)
Is there a better way of doing it?
Write a gulp file, lets call it 'jquery-noconflict.js'
var through = require('through2');
var gutil = require('gulp-util');
var fs = require('fs');
module.exports = function(){
var stream = through.obj(function(file, enc, cb) {
if (file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
return cb();
}
if (file.isBuffer()) {
var contents = file.contents.toString();
file.contents = Buffer.concat([new Buffer('jQuery(document).ready(function(){'), file.contents, new Buffer('})')]);
}
cb(null, file);
}, function(){
})
return stream;
};
You might need to 'npm install through2'
now in your gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var jquery = require('./jquery-noconflict');
gulp.task('compile-js', function(){
gulp.src('./stuff.js')
.pipe(concat('script.js'))
.pipe(jquery())
.pipe(gulp.dest('./public/javascripts/'))
})

Run gulp plugin on single file

I'm trying to write a minify function that can be used to minifiy html, css, and js depending on file type. I would like to use the existing gulp plugins for these 3 minification processes to do the actual minification. The problem I'm having is I don't know how to call a plugin on a single vinyl file. Here is what I have so far:
var cssmin = require('gulp-cssmin');
var htmlmin = require('gulp-minify-html');
var uglify = require('gulp-uglify');
var minifiers = {
js: uglify,
css: cssmin,
html: htmlmin
};
function minify(options) {
var options = options || {};
return tap(function(file){
var fileType = file.path.split('.').pop();
options = options[fileType] || options
var minifier = minifiers[fileType];
if(!minifier)
console.error("No minifier for " + fileType + " - " + file.path);
// WHAT DO I DO HERE? This doesn't work but I want to do something similar
file.pipe(minifier(options));
});
}
I would like to be able to call the minify function like this:
gulp.src(['test.html', 'test.css', 'test.js'])
.pipe(minify());
Use gulp-filter.
var gulpFilter = require('gulp-filter');
var jsFilter = gulpFilter('**/*.js');
var cssFilter = gulpFilter('**/*.css');
var htmlFilter = gulpFilter('**/*.html');
gulp.task('default', function () {
gulp.src('assets/**')
.pipe(jsFilter)
.pipe(uglify())
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe(cssmin())
.pipe(cssFilter.restore())
.pipe(htmlFilter)
.pipe(htmlmin())
.pipe(htmlFilter.restore())
.pipe(gulp.dest('out/'));
});
Will work for single files too but globs are more futureproof :)
SOLUTION:
I ended up using gulp-filter to solve the issue, but it was fairly tricky to get it working in a reusable way. Here is my final code:
var cssmin = require('gulp-cssmin');
var htmlmin = require('gulp-htmlmin');
var uglify = require('gulp-uglify');
var lazypipe = require('lazypipe');
function getFilter(type) {
// create a filter for the specified file type
return filter('**/*.' + type);
}
var minify = function() {
var jsFilter = getFilter('js'),
cssFilter = getFilter('css'),
htmlFilter = getFilter('html');
var min = lazypipe()
.pipe(function(){return jsFilter;})
.pipe(uglify)
.pipe(jsFilter.restore)
.pipe(function(){return cssFilter;})
.pipe(cssmin)
.pipe(cssFilter.restore)
.pipe(function(){return htmlFilter;})
.pipe(htmlmin)
.pipe(htmlFilter.restore);
return min();
};
To run gulp plugin on a single file you need to do the following:
var stream = minifier(options);
stream.once('data', function(newFile) {
file.contents = newFile.contents;
})
stream.write(file);