Batch nested templates in subdirectories using gulp-compile-handlebars - gulp

I'm using gulp compileHandlebars to compile my handlebars templates and create a page using json data and that's working great... Problem is I want to nest my handlebars templates in subdirectories but when I do this the batch process cant find the templates anymore after I add: **/*.handlebars to the batch path. See below:
gulp.task('compileHandlebars', function () {
delete require.cache[require.resolve('./src/layout.json')]
var buildSettings = require('./src/layout.json');
var templateData = buildSettings,
options = {
batch : ['./src/assets/templates/**/*.handlebars']
}
gulp.src('./src/index.handlebars')
.pipe(handlebars(templateData, options))
.pipe(rename('index.html'))
.pipe(cleanhtml())
.pipe(gulp.dest('./dist'))
.pipe(livereload());
});

The docs on npm say that batch requires an array of file paths but the example shows an array with a directory path. Your example is using blob syntax which won't work. It doesn't look like that batch will recursively look into sub-directories either... so I think you will have to make an array that includes a parent directory path for each handlebars file.
Its a bummer, I know. But you could probably automate the process of retrieving the handlebar file paths using gulp-filenames and slice off the filename from each path to get an array of directories.

Related

Modify existing YAML values using Gulp

I'm pretty new to YAML and I feel like I missing something or making my own life harder than it should be.
I'm using Gulp to run a bunch of tasks to minify CSS/JS and lint my code, but for the final build I need to modify a YAML file that contains some configuration values.
This is part of my YAML file:
- adx_name: RedirectUri
adx_sitesettingid: 3745e5fe-2b95-eb11-b1ac-000d3a2cd507
adx_value: https://example.com/signin
The YAML file contains a bunch of config but I just need to change the adx_value where adx_name = RedirectUri.
I don't seem to be able to find any Gulp plugins that work with YAML directly, other than those that are able to read YAML or append to YAML files. What I need to be able to do it edit the file and write new values at the correct location in the file.
You can do this pretty easily with gulp-replace.
gulp.task('yaml-replace', function () {
return gulp.src('./test.yaml')
.pipe(replace(/(?<=adx_name:\s)(RedirectUri)/g, 'myReplacement')) // positive lookbehind
.pipe(gulp.dest('./yaml'));
});
The replace function can take a string or regex and replace with a string or function.
Result:
- adx_name: myReplacement
adx_sitesettingid: 3745e5fe-2b95-eb11-b1ac-000d3a2cd507
adx_value: https://example.com/signin

I am looking for a way to have gulp watch for a json of directories

var paths = {
css: "css/**/*.{scss,sass}",
js: "js/**/*.js",
other: ["fonts/**/*.ttf", "images/**/*.{gif,png,jpg}", "includes/**"]
}
I can run
gulp.watch(paths.css, css); //compile sass and copy to template directory
gulp.watch(paths.js, js); //compile js and copy to template directory
gulp.watch(paths.other, copy_other); //when something changes in these, copy to template output directory
But that doesn't remove deleted files from the template output directory. When I remove lets say js/test.js it just compiles all js and copies them to output but doesn't remove test.js from template output directory.
I want to have an additional watch thread looking for deleted files in every path of the given path json object
gulp.watch(paths).on("unlink", function(path) {
delete(path);
}); //delete() takes filename and deletes it in template output directory
Doesn't work because watch expects a string not a json object:
TypeError: expected a string
Just using cwd()+"/**" complains about too many files.
Error: ENOSPC: System limit for number of file watchers reached...

How to use gulp-newer?

I'm new to gulp and I tried to follow the documentation in https://www.npmjs.com/package/gulp-newer to understand how it works. However its not working as expected for the below task. I think I'm missing something obvious.
Here's the folder structure,
temp
file1.js
file2.js
new
file1.js
file3.js
change
<empty initially>
I want to compare temp folder with new folder and if there are any new files in new folder(which was not present in temp earlier) then move those files to change folder. This is just me trying to understand how gulp-newer works. Am I doing it right?
gulp.task('newer', function() {
return gulp.src('temp/*.js')
.pipe(newer('new/*.js'))
.pipe(gulp.dest('change'))
});
However when I run this task it just copy all the files in temp folder to change folder. So after task run change folder has file1.js and file2.js. I'm expecting just file3.js to be present in change(since that's a new file). Correct me if my understanding with the approach is incorrect.
From gulp-newer:
Using newer with many:1 source:dest mappings Plugins like gulp-concat
take many source files and generate a single destination file. In this
case, the newer stream will pass through all source files if any one
of them is newer than the destination file. The newer plugin is
configured with the destination file path.
and the sample code:
var gulp = require('gulp');
var newer = require('gulp-newer');
var concat = require('gulp-concat');
// Concatenate all if any are newer
gulp.task('concat', function() {
// Add the newer pipe to pass through all sources if any are newer
return gulp.src('lib/*.js')
.pipe(newer('dist/all.js'))
.pipe(concat('all.js'))
.pipe(gulp.dest('dist'));
});
it seems that you need to pass in all the files already concatenated to newer. In your case:
gulp.task('newer', function() {
return gulp.src('temp/*.js')
.pipe(newer('new/*.js'))
.pipe(concat('*.js'))
.pipe(gulp.dest('change'))
});
Also, since newer checks the files modified date make sure that the files are actually newer. I know it's obvious, but I'm usually stuck on "obvious" stuff.
May I also suggest gulp-newy in which you can manipulate the path and filename in your own function. Then, just use the function as the callback to the newy(). This gives you complete control of the files you would like to compare.
This will allow 1:1 or many to 1 compares.
newy(function(projectDir, srcFile, absSrcFile) {
// do whatever you want to here.
// construct your absolute path, change filename suffix, etc.
// then return /foo/bar/filename.suffix as the file to compare against
}

Using gulp for compiling of changed files only

I have lots of .jade, .styl and .coffee files resided in different subfolders.
I’d like to compile only changed files when they are changed.
I’m using gulp and I’ve come up to the following pattern:
var watch = require('gulp-watch'),
watch(['app/**/*.styl'], function (e) {
gulp.src(e.path)
.pipe(stylus({use: nib()}))
.pipe(gulp.dest('./app'))
However this pattern stores compiled file into the root of ./app folder, but not to the folder where the source file resides.
I’ve tried lots of stuff and all in vain.
The problem is that there is a lack of documentation and samples for gulp-watch and others.
Could anybody tell me how to store compiled file to the its source’s folder?
The problem is that you pass e.path (i.e. the full path of every changed file) as a glob pattern to gulp.src(). This means that your glob pattern does not actually contain a glob (like * or **), in which case the directory where the file is located is used as the default value for the base option to gulp.src(). When the files are then written with gulp.dest() that base option causes the entire directory structure to get stripped.
The solution is to use the streaming variant of gulp-watch instead of the callback variant ...
gulp.src('app/**/*.styl')
.pipe(watch('app/**/*.styl'))
.pipe(stylus({use: nib()}))
.pipe(gulp.dest('./app'));
... or provide an appropriate base option to the callback variant:
watch(['app/**/*.styl'], function (e) {
gulp.src(e.path, {base: 'app'})
.pipe(stylus({use: nib()}))
.pipe(gulp.dest('./app'));
});

Load source files from JSON file in Gulpjs

I know it's a basic question, but I couldn't find a proper answer.
Is there a way of storing a list of my project's source files in a JSON file and load it on gulpfile.js? For example, instead of doing:
gulp.src(['a.js', 'b.js'])
Do something like:
var sources = some_load_file_func('sources.json');
gulp.src(sources.js_files))
A gulpfile is just node, and in node you can simply use require on JSON files, like so:
var sources = require('sources.json');
Now sources will be an object (or whatever is in your JSON file).