How can I combine these two Gulp tasks into a single one? - javascript

Right now I have two tasks: templates and js. templates has to run first so that changes are be picked up by js. I want to combine these, eliminating the intermediate file, so that the task works like this:
Compile and concatenate templates into a single chunk of JS
Concatenate that chunk with the rest of my application's JS code
Output the whole thing as a single file
How can I do this?
Here's my current code:
var gulp = require('gulp');
var handlebars = require('gulp-handlebars');
var concat = require('gulp-concat');
var wrap = require('gulp-wrap');
var declare = require('gulp-declare');
// Compile Handlebars templates into JS
gulp.task('templates', function() {
return gulp.src('./templates/*.hbs')
.pipe(handlebars({
handlebars: require('handlebars')
}))
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'templates',
noRedeclare: true,
}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('./js/'));
});
// Concatenate and minify application JS
gulp.task('js', function() {
return gulp.src('./js/*.js')
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));

For me the easyest and cleaner way is to call one task after the other with
gulp.task('js', ['templates'], function(){
....
In this way the js task need the execution of templates task
Keeping the compilation and the final concat in 2 separate task it's not that bad for me.
Let me know if it's not a viable solution for you
EDIT
in one single task you can try to use merge-stream
and do
var merge = require('merge-stream');
gulp.task('templates', function() {
var jsStream = gulp.src('./js/*.js')
.pipe(concat('all.js'));
var templateStream = gulp.src('./templates/*.hbs')
.pipe(handlebars({
handlebars: require('handlebars')
}))
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'templates',
noRedeclare: true,
}))
.pipe(concat('templates.js'));
merge(jsStream, templateStream)
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
});
I've done it by heart without trying so my not work as intended

Related

How to Precompile Handlebars templates and convert to html using gulp-compile-handlebars in batch

I am using express and node in server side and handlebars as templating engine.
Now from the official documentation of gulp-compile-handlebars I came to know about pre-compiling technique of handlebars templates, which I am doing as below -
const handlebars = require('gulp-compile-handlebars');
const rename = require('gulp-rename');
gulp.task('compile-handlebars', function () {
var templateData = {
data: 'Kaanon'
},
options = {
batch : ['./views/partials'],
helpers : {
capitals : function(str){
return str.toUpperCase();
}
}
}
return gulp.src('views/home.handlebars')
.pipe(handlebars(templateData, options))
.pipe(rename('home.html'))
.pipe(gulp.dest('build'));
});
But this allows me to precompile the handlebar templates one by one, whereas I want a process which will compile all files to html in that process itself.
e.g SASS compilation and converting to Css files I am doing like this,
const sass = require('gulp-sass');
gulp.task('styles', function() {
gulp.src('sass/*.scss')
.pipe(sass(compile_config).on('error', sass.logError))
.pipe(gulp.dest('./assets/css/'))
});
This converts all sass files to respective css files.
I want a similar thing for my handlebar templates.
Attaching my directory structure for better understanding,

How can I use gulp to replace a string in a file?

I am using gulp to uglify and make ready my javascript files for production. What I have is this code:
var concat = require('gulp-concat');
var del = require('del');
var gulp = require('gulp');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var js = {
src: [
// more files here
'temp/js/app/appConfig.js',
'temp/js/app/appConstant.js',
// more files here
],
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src).pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'))
.pipe(gzip(gzip_options))
.pipe(gulp.dest('content/bundles/'));
});
What I need to do is to replace the string:
dataServer: "http://localhost:3048",
with
dataServer: "http://example.com",
In the file 'temp/js/app/appConstant.js',
I'm looking for some suggestions. For example perhaps I should make a copy of the appConstant.js file, change that (not sure how) and include appConstantEdited.js in the js.src?
But I am not sure with gulp how to make a copy of a file and replace a string inside a file.
Any help you give would be much appreciated.
Gulp streams input, does all transformations, and then streams output. Saving temporary files in between is AFAIK non-idiomatic when using Gulp.
Instead, what you're looking for, is a streaming-way of replacing content. It would be moderately easy to write something yourself, or you could use an existing plugin. For me, gulp-replace has worked quite well.
If you want to do the replacement in all files it's easy to change your task like this:
var replace = require('gulp-replace');
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src)
.pipe(replace(/http:\/\/localhost:\d+/g, 'http://example.com'))
.pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'))
.pipe(gzip(gzip_options))
.pipe(gulp.dest('content/bundles/'));
});
You could also do gulp.src just on the files you expect the pattern to be in, and stream them seperately through gulp-replace, merging it with a gulp.src stream of all the other files afterwards.
You may also use module gulp-string-replace which manages with regex, strings or even functions.
Example:
Regex:
var replace = require('gulp-string-replace');
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace(new RegExp('#env#', 'g'), 'production'))
.pipe(gulp.dest('./build/config.js'))
});
String:
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace('environment', 'production'))
.pipe(gulp.dest('./build/config.js'))
});
Function:
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace('environment', function () {
return 'production';
}))
.pipe(gulp.dest('./build/config.js'))
});
I think that the most correct solution is to use the gulp-preprocess module. It will perform the actions you need, depending on the variable PRODUCTION, defined or not defined during the build.
Source code:
/* #ifndef PRODUCTION */
dataServer: "http://localhost:3048",
/* #endif */
/* #ifdef PRODUCTION **
dataServer: "http://example.com",
/* #endif */
Gulpfile:
let preprocess = require('gulp-preprocess');
const preprocOpts = {
PRODUCTION: true
};
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src)
.pipe(preprocess({ context: preprocOpts }))
.pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'));
}
This is the best solution because it allows you to control the changes that are made during the build phase.
There I have a versioning specific example for your reference.
let say you have version.ts file and it contains the version code inside it. You now can do as the follows:
gulp.task ('version_up', function () {
gulp.src (["./version.ts"])
.pipe (replace (/(\d+)\.(\d+)(?:\.(\d+))?(?:\-(\w+))?/, process.env.VERSION))
.pipe (gulp.dest ('./'))
});
the above regex works for many situation on any conventional version formats.

How can I achieve this using gulp?

I am enumerating the subdirectories in a directory. For each sub directory I would like to apply a number of gulp activities like less compilation, and then create an output file specific to that subdirectory.
I would like the gulp process to continue, as further transformation steps need to be performed later.
Can someone help me understand how I can create these files half way through the "gulp pipeline"?
This seems quite interesting to achieve and gulp has no limitations at all.
I will give you detailed example how I have managed to accomplish such a task a while ago.
Let assume that you have directoryA. Subdirectories childA, childB and childC are contained into directoryA. So basically your tree structure looks like:
directoryA
--childA
--childB
--childC
I am always looking for a flexible solutions so I would suggest to include a JSON file in each subdirectory naming the tasks you would like to running. Using fs you can access these files. You can also use run-sequence to execute gulp tasks synchronously.
For demo purposes place a file named manifest.json inside childA subdirectory.
Manifest.json contains the following declarations:
{
"filesToProccess" : ["./childA/*.js", "./childB/*.js"],
"tasksToRun" :["taskA", "taskB"]
}
Finally gulpfile would like this:
'use strict';
//dependencies declared into package.json
//install them using npm
var gulp = require('gulp'),
fs = require('fs'),
runSequence = require('run-sequence'),
path = require('path');
//these two array will keep the actions you have included into manifest file.
var filesHolder = [], tasksHolder = [];
gulp.task('taskA', function () {
return gulp.src(filesHolder)
.pipe(whatever)
.pipe(gulp.dest('whatever')); //chailed actions
});
gulp.task('taskB', function () {
return gulp.src(filesHolder)
.pipe(whatever)
.pipe(gulp.dest('whatever'));
});
//a simple utility function to read all subdirectories of directoryA
function getDirectories(srcpath) {
return fs.readdirSync(srcpath).filter(function(file) {
return fs.statSync(path.join(srcpath, file)).isDirectory();
});
}
//finally insert the default gulp task
gulp.task('default', function(){
var manifest;
//map directory's A subdirectories
var availableDirs = getDirectories("./directoryA");
//finally loop the available subdirectories, load each manifest file and
availableDirs.forEach(function(subdir) {
manifest = require("./directoryA/"+subdir+"manifest.json");
filesHolder = manifest.filesToProccess;
tasksHolder = manifest.tasksToRun;
runSequence( tasksHolder , function () {
console.log( " Task ended :" + tasksHolder + " for subdirectory : " + subdir);
});
});
});

How to setup jade includes with gulp-jade

I am currently using gulp-jade and I am struggling on how to setup Jade includes in my gulpfile.js.(For clarification, I am referring to this here http://jade-lang.com/reference/includes/) The following is the code in my gulpfile.js
var gulp = require('gulp');
var browserSync = require('browser-sync');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var jade = require('gulp-jade');
var jshint = require('gulp-jshint');
var fileinclude = require('gulp-file-include');
var reload = browserSync.reload;
//compile jade to html
gulp.task('templates', function() {
var YOUR_LOCALS = {};
gulp.src('./app/jade/*.jade')
.pipe(jade({
locals: YOUR_LOCALS
}))
.pipe(gulp.dest('./dist/'))
});
//reload files, once jade compilation happens
gulp.task('jade-watch', ['templates'], reload);
//Sass task for live injecting into all browsers
gulp.task('sass', function () {
gulp.src('./app/scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('./dist/css'))
.pipe(reload({stream: true}));
});
//Separate task for the reaction to js files make change even without compilation and what not
gulp.task('compress', function() {
return gulp.src('./app/js/*.js')
.pipe(uglify())
.pipe(gulp.dest('./dist/js'));
});
gulp.task('js-watch', ['compress'], reload);
//Serve and watch the scss/jade files for changes
gulp.task('default', ['sass', 'templates', 'compress'], function () {
browserSync({server: './dist'});
gulp.watch('./app/**/*.jade', ['jade-watch']);
gulp.watch('./app/scss/*.scss', ['sass']);
gulp.watch('./app/js/*.js', ['js-watch']);
});
I know it is quite a bit to parse through. I am hoping it is a standard something, that won't take too long. If you are interested in seeing the entire file structure, it can be seen at my github here https://github.com/CharlieGreenman/Gulp-with-foundation-and-sass
Thank you, and any help would be more than appreciated!
I wrote a Gulp plugin that simplifies your includes by allowing you to add some arbitrary paths to resolve includes and extends to, so you don't have to worry so much about relative pathing. Take a look: https://github.com/tomlagier/gulp-jade-modules
Turns out it was really simple. There were one thing I was doing wrong
I was using includes ../includes/head instead of include ../includes/head (using includes actually worked for me in grunt, upon further research I saw I was using it wrong for gulp.).

Load HTML Template for use with knockout component via Browserify

I'm using browserify and knockout and am trying to load html files for knockout component templates. I have browserify successfully loading javascript files, but I'm unclear on how to get it to load html files.
I'm trying to do something like this:
(function() {
var ko = require('./lib/knockout/dist/knockout.js');
var authenticationViewModel = require('./viewmodels/authentication.js');
var authenticationView = require('./views/authentication.html');
ko.components.register('authentication', {
template: authenticationView,
viewModel: authenticationViewModel
});
})();
But the template is obviously not loading. Can someone please explain to me how this is to be accomplished?
This is what I have in my gulpfile.js to get browserify to work with .js files:
gulp.task('browserify', function () {
var browserified = transform(function(filename) {
var b = browserify(filename);
return b.bundle();
});
return gulp.src([paths.appJs])
.pipe(browserified)
.pipe(gulp.dest(paths.public));
});
I'm looking into the html-browserify plugin:
https://www.npmjs.com/package/html-browserify
The example they are using looks like this:
gulp.task('js', function() {
gulp.src('js/app.js')
.pipe(browserify({
insertGlobals: true,
transform: html
}))
.pipe(concat('app.js'))
.pipe(gulp.dest('./public/js'));
});
But I'm unclear on how to reconcile this example with my current code that is already working.
brfs should be one option.
In one of my own apps I use gulp to read some template files, combine them into an object, and write a JSON file that I load in my (browserified) app.
I ended up finding and using partialify. It works perfectly for inporting html files as dependencies.
//Gulp Plugins
var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var partialify = require('partialify');
//Browserify
gulp.task('browserify', function() {
return browserify()
.add(paths.browserifyEntry)
.bundle()
.pipe(source('main.js'))
.pipe(gulp.dest(paths.public));
});

Categories

Resources