As of now I just have two gulp tasks, ex gulp.task('handlebars-index'), gulp.task('handlebars-about'). Below is code from the docs, https://www.npmjs.org/package/gulp-compile-handlebars
I am not sure how I can handle the task for two .handlebars files.
var gulp = require('gulp');
var handlebars = require('gulp-compile-handlebars');
var rename = require('gulp-rename');
gulp.task('handlebars', function () {
var templateData = {
firstName: 'Kaanon'
},
options = {
ignorePartials: true, //ignores the unknown footer2 partial in the handlebars template, defaults to false
partials : {
footer : '<footer>the end</footer>'
},
batch : ['./src/partials'],
helpers : {
capitals : function(str){
return str.toUpperCase();
}
}
}
// here how do I add an index.html and say and about.html?
return gulp.src('src/index.handlebars')
.pipe(handlebars(templateData, options))
.pipe(rename('index.html'))
.pipe(gulp.dest('dist'));
});
You can see with the above the task basically takes the index.handlebars then compiles it and creates an index.html file.
If I added an array of handlebar files how will the task know how to create the .html version?
return gulp.src(['src/index.handlebars','src/about.handlebars'])
.pipe(handlebars(templateData, options))
.pipe(rename('index.html'))
.pipe(rename('about.html'))
.pipe(gulp.dest('dist'));
The above won't work obviously.
Gulp-rename also takes a function where you can change only part of the path.
return gulp.src('src/*.handlebars')
.pipe(handlebars(templateData, options))
.pipe(rename(function(path) {
path.extname = '.html';
}))
.pipe(gulp.dest('dist'));
https://github.com/hparra/gulp-rename#usage
Related
I have two folders, dist and partials, the 'dist' folder contains the index.html file and the 'partials' folder contains header.html, navbar.html, and footer.html files. I want to include these partial files into index.html. I tried the gulp-file-include plugin, It works fine but I want that whenever I perform any changes into any partial file, The index.html file should be updated. I'm not able to do this with the gulp-file-include plugin, Please any other solution...?
gulpfile.js
'use strict'
const fileinclude = require('gulp-file-include');
const gulp = require('gulp');
gulp.task('fileinclude', function() {
return gulp.src(['dist/index.html'])
.pipe(fileinclude({
prefix: '##',
basepath: '#file'
}))
.pipe(gulp.dest('dist'));
});
index.html
##include('../partials/header.html')
##include('../partials/navbar.html')
##include('../partials/footer.html')
Use gulp.watch(...) to track all changes, it's not just for html. Any files in gulp are tracked using this method.
const gulp = require('gulp');
const include_file = require('gulp-file-include');
gulp.task('include', () => {
return gulp.src('./res/*.html')
.pipe(include({
prefix: "##",
basepath: "#file"
}))
.pipe(gulp.dest('./public'));
});
gulp.task('watch', () => {
gulp.watch('./res/*.html', gulp.series('include'));
})
also my variant:
const { src, dest, watch } = require('gulp'),
include_file = require('gulp-file-include');
function include() {
return src('./res/*.html')
.pipe(file_include({
prefix: '#',
basepath: '#file'
}))
.pipe(dest('./public/'));
}
function watching() {
watch('./res/*.html', include);
}
exports.watch = watching;
then:
gulp watch
I have the following two tasks:
gulp.task('compress', () => {
return gulp.src('app/static/angular/**/*.js')
.pipe(concat('build.js'))
.pipe(gulp.dest('./app/static'));
});
gulp.task('templates', () => {
return gulp.src('app/static/angular/**/*.html')
.pipe(htmlmin())
.pipe(angularTemplateCache('templates.js', {
module: 'myApp',
root: '/static/angular'
}))
.pipe(gulp.dest('./app/static'))
});
And it works fine, but I want them both concatenated into build.js -- how can I combine these two?
In the end I used merge-stream to merge the two streams into one output file:
var gulp = require('gulp');
var concat = require('gulp-concat');
var htmlmin = require('gulp-htmlmin');
var angularTemplateCache = require('gulp-angular-templatecache');
var merge = require('merge-stream');
gulp.task('build', () => {
var code = gulp.src('app/static/angular/**/*.js');
var templates = gulp.src('app/static/angular/**/*.html')
.pipe(htmlmin())
.pipe(angularTemplateCache({
module: 'myApp',
root: '/static/angular'
}));
return merge(code, templates)
.pipe(concat('build.js'))
.pipe(gulp.dest('./app/static'));
});
gulp.task('default', ['build']);
I assume the above task mentioned is in separate file say compress.js inside tasks folder
In gulpfile.js you can use below code :
//Include require-dir to include files available in tasks directory
var requireDir = require('require-dir');
// And Take the tasks directory
requireDir('./tasks');
Then you can create a build task as below in gulpfile.js:
gulp.task('build', ['compress', 'templates']);
So I have asimple gulp task function which currently converts my main.jsx to a main.js file:
gulp.task("bundle", function () {
return browserify({
entries: "./app/main.jsx",
debug: true
}).transform(reactify)
.bundle()
.pipe(source("main.js"))
.pipe(gulp.dest("app/dist"))
});
I was wondering if it would be possible to put multiple bundles in this gulp.task?
My ideal outcome would be being able to do:
main.jsx to main.js
otherPage.jsx to otherPage.js
otherPage2.jsx to otherPage2.js
All in one gulp task.
I have searched onliine but cannot seem to find anything relevant, any help or advice is appreciated, thank you in advance.
If you want to create a bundle for each file you need to loop over the respective files, create a stream for each file and then merge the streams afterwards (using merge-stream):
var merge = require('merge-stream');
gulp.task("bundle", function () {
var files = [ "main", "otherPage", "otherPage2" ];
return merge(files.map(function(file) {
return browserify({
entries: "./app/" + file + ".jsx",
debug: true
}).transform(reactify)
.bundle()
.pipe(source(file + ".js"))
.pipe(gulp.dest("app/dist"))
}));
});
The above requires that you maintain a list of files manually as an array. It's also possible to write a task that bundles all .jsx files in the app directory without having to maintain an explicit array of the files. You just need the glob package to determine the array of files for you:
var merge = require('merge-stream');
var glob = require('glob');
var path = require('path');
gulp.task("bundle", function () {
var files = glob.sync('./app/*.jsx');
return merge(files.map(function(file) {
return browserify({
entries: file,
debug: true
}).transform(reactify)
.bundle()
.pipe(source(path.basename(file, '.jsx') + ".js"))
.pipe(gulp.dest("app/dist"))
}));
});
When I make changes to .jade files I want to Gulp task run only for that file, not for all files. For that I'm using gulp-changed. It's working fine, until I make changes to files that affect to global layout, eg _header.jade, _layout.jade. When I make changes to that files nothing happens. All my layout files have _ before title. How can I solve this issue?
Here is my gulpfile some lines
gulp.task('jade', function() {
return gulp.src('dev/templates/**/!(_)*.jade')
.pipe(plumber({
errorHandler: onError
}))
.pipe(changed('public', {extension: '.html'}))
.pipe(jade({
pretty: true,
}))
.pipe(gulp.dest('public'))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task('watch', function() {
gulp.watch('dev/templates/**/*.jade', gulp.series('jade'));
});
First thing I would do is to refactor out your jade compilation task into a separate function. That allows you to parameterize your jade compilation so that you can run it on one or more files of your choice:
function compileJade(files) {
return gulp.src(files, {base:'dev/templates'})
.pipe(plumber({
errorHandler: onError
}))
.pipe(jade({
pretty: true,
}))
.pipe(gulp.dest('public'))
.pipe(browserSync.reload({
stream: true
}));
}
Your existing jade task now simply calls that function:
gulp.task('jade', function() {
return compileJade('dev/templates/**/!(_)*.jade');
});
If a changed file is a partial (starts with _) we need to be able to determine which other files are affected by that change. This is facilitated by the jade-inheritance library:
var JadeInheritance = require('jade-inheritance');
var path = require('path');
function isPartial(file) {
return path.basename(file).match(/^_.*/);
}
function findAffectedFiles(changedFile) {
return new JadeInheritance(changedFile, 'dev/templates', {basedir: 'dev/templates'})
.files
.filter(function(file) { return !isPartial(file); })
.map(function(file) { return 'dev/templates/' + file; })
}
Finally whenever a file changes we call the compileJade function for the affected files only:
gulp.task('watch', function() {
gulp.watch('dev/templates/**/*.jade').on('change', function(changedFile) {
return compileJade(isPartial(changedFile) ? findAffectedFiles(changedFile) : changedFile);
});
});
I have a directory with a bunch of jade templates, and a grunt task that compiles all of them to individual html files.
I'd like to have a watch task that recompiles a template when it changes, but right now my task recompiles every template when any of them change.
Here is a demo in a gist.
Is there a succinct way to write a task that recompiles a template when it changes, but not all of the other templates?
the solution is to add a filter function to the files list:
var fs = require('fs');
var join = require('path').join;
module.exports = function(grunt) {
grunt.initConfig({
jade: {
files: {
src: ['*.jade'],
dest: './',
expand: true,
ext: '.html',
filter: function(destDir, src) {
var dest = join(destDir, src.replace(/jade$/, 'html'));
var destMod;
try {
destMod = +fs.lstatSync(dest).mtime;
} catch (e) {
if (e.code === 'ENOENT') {
// there's no html file, so ensure that the
// jade file is compiled by returning true
return true;
}
throw e;
}
return fs.lstatSync(src).mtime > destMod;
}
}
},
watch: {
files: ['*.jade'],
tasks: ['jade']
}
});
grunt.loadNpmTasks('grunt-contrib-jade');
grunt.loadNpmTasks('grunt-contrib-watch');
};