How to concat multiple jQuery files into one using Gulp? - 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/'))
})

Related

gulp gulp-watch don't work

I try following code.
var gulp = require("gulp");
var ps = require('child_process').exec;
var watch = require('gulp-watch');
gulp.task('exec_file', function() {
var command = "/mnt/c/pg/expect/folder_sync";
ps(command , function (err, stdout, stderr) {
console.log(stdout);
});
});
gulp.task("watch", function() {
var targets = [
'./**'
];
return watch(targets, ['exec_file']);
});
However the code make a error.
What should I do?
Inside of the watch, you have to inform Gulp which task to start.
Replace the following line:
return watch(targets, ['exec_file']);
with this:
watch(targets, function(){
gulp.start('exec_file');
})
or with this:
watch(targets).on('change', function(){ gulp.start('exec_file')});
P.S I'm not sure if you have to return anything.

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.

Browserify is not replacing the class token

I am using the following gulpfile to compile my javascript code from ES6 to ES5.
var gulp = require('gulp');
var gutil = require('gulp-util');
var cssnano = require('gulp-cssnano');
var autoprefixer = require('gulp-autoprefixer');
var notify = require("gulp-notify");
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var browserify = require('browserify');
var watchify = require('watchify');
var babel = require('gulp-babel');
var babelify = require('babelify');
var uglify = require('gulp-uglify');
//...
gulp.task('js', function () {
return buildScript('index.js', false);
});
function buildScript(file, watch) {
var props = {
entries: [folder_source + '/javascript/' + file],
debug : true,
transform: [babelify]
};
// watchify() if watch requested, otherwise run browserify() once
var bundler = watch ? watchify(browserify(props)) : browserify(props);
function rebundle() {
var stream = bundler.bundle();
return stream
.on('error', handleErrors)
.pipe(source(file))
.pipe(gulp.dest(folder_dest + '/javascript/build/'));
}
// listen for an update and run rebundle
bundler.on('update', function() {
rebundle();
gutil.log('Rebundle...');
});
// run it once the first time buildScript is called
return rebundle();
}
function handleErrors() {
var args = Array.prototype.slice.call(arguments);
notify.onError({
title: 'Compile Error',
message: '<%= error.message %>'
}).apply(this, args);
this.emit('end'); // Keep gulp from hanging on this task
}
Everything works fine until Im starting to actually use ES6.
Example Source (index.js):
class Car{
}
Example Compiled (app.js):
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
class Car {}
},{}]},{},[1])
As you can see there is still ES6 code in the compiled file.
It seems like babelify is not doing its jop. I already tried several other gulp files from around the web, but I always got the same result.
Thank you!
Thanks to loganfsmyth I was able to solve the problem by adding the following to the props array:
transform: [[babelify, {presets: ["es2015"]}]]

Sequencing tasks with gulp

I'm a bit stumped with gulp. Based on the docs, in order to get sequential execution, I should be returning the stream from my tasks, so i tried to do the below for my gulpfile. But as best I can tell, there's a race condition. Half the time I get ENOENT, lstat errors, the other half it succeeds, but my deployDir has weird folder names and missing files all over.. Am I missing something? Is there a trick to this?
var gulp = require('gulp'),
filter = require('gulp-filter'),
mainBowerFiles = require('main-bower-files'),
del = require('del'),
inject = require("gulp-inject"),
uglify = require('gulp-uglifyjs');
var config = {
bowerDir: 'src/main/html/bower_components',
cssDir: 'src/main/html/css/lib',
fontsDir: 'src/main/html/fonts/lib',
imgDir: 'src/main/html/img/lib',
jsDir: 'src/main/html/js/lib',
deployDir: 'src/main/resources/html'
};
gulp.task('default', ['clean', 'bowerdeps', 'dev']);
gulp.task('clean', function() {
return del([
config.cssDir,
config.fontsDir,
config.jsDir,
config.deployDir
]);
});
gulp.task('dev', function() {
return gulp
.src(['src/main/html/**', '!src/main/html/{bower_components,bower_components/**}'])
.pipe(gulp.dest(config.deployDir));
});
gulp.task('bowerdeps', function() {
var mainFiles = mainBowerFiles();
if(!mainFiles.length) return; // No files found
var jsFilter = filterByRegex('.js$');
var cssFilter = filterByRegex('.css$');
var fontFilter = filterByRegex('.eot$|.svg$|.ttf$|.woff$');
return gulp
.src(mainFiles)
.pipe(jsFilter)
.pipe(gulp.dest(config.jsDir))
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe(gulp.dest(config.cssDir))
.pipe(cssFilter.restore())
.pipe(fontFilter)
.pipe(gulp.dest(config.fontsDir));
});
// Utility Functions
var filterByRegex = function(regex){
return filter(function(file){
return file.path.match(new RegExp(regex));
});
};
Dependencies run always parallel: ['clean', 'bowerdeps', 'dev'].
https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md
You can use run-sequence for sequencing tasks.
Other thing: del doesn't return a stream. Use callback instead:
gulp.task('clean', function(cb) {
del([
config.cssDir,
config.fontsDir,
config.jsDir,
config.deployDir
], cb);
});

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);