How do I delete the regular(jpg, png ) images after converting them to webp usging gulp? - gulp

I'm new to gulp. Trying to optimize the images and convert them into webp format. I was able to achieve that using gulp-webp. But it seems there are now two version of the images inside my dist/img folder one is the original and a webp version. So how do I get only the webp not the original one inside my dist/img folder?
Here how my project directories look like:
project
|-dist
|-css
|-img
|-js
|-src
|-css
|-img
|-js
gulp.js
...
Here is webp conversion function:
function webpImage() {
return src('dist/img/**/*.{jpg,png}')
.pipe(imagewebp())
.pipe(dest('dist/img'))
}

I would first say you should not delete source file, it is ok to keep them. What you want to do is having to different destinations. One of which should be deployed (the compiled, minified and webp for example) and the other should be version and used in your cdci pipelines perhaps.
But then, if you really want to remove the source file, you can use gulp-clean while being in a gulp script.
Your gulp clean script could look like that :
const { src, task } = require('gulp');
const clean = require("gulp-clean");
const logger = require('node-color-log');
function cleanImagesTask() {
const root = "path/to/images/you/want/to/delete";
logger.color('yellow').log(`Clean images`);
return src(root,{allowEmpty: true},{read: false}).pipe(clean({force:true}));
};
const cleanImagesFolder = task('clean:images', cleanImagesTask);
exports.cleanImagesFolder = cleanImagesFolder;
And if you want to deploy in a different dest, could use something similar to :
const { src, dest, task } = require( 'gulp' );
const logger = require('node-color-log');
function copyImagesToDest(callback) {
const imagesSource = "path/to/your/images/**/*";
const imagesDestination = "path/to/destination/";
logger.color('green').log(`Copy images from ${artifactData} to: ${destination}`);
return src(imagesSource)
.pipe(dest(destination))
.on('end', function () {
logger.color('green').log(`Copy to: ${destination}`);
callback();
});
};
const copyImages = task('copy:images', copyImagesToDest);
exports.copyImages = copyImages ;

Related

Seeking wrapper to run Gulp pipe operations in parallel

I've got a fairly simple Gulp task that simply scoops some files that match a glob and uploads them to Google Cloud via the gulp-gcloud-publish package as in the following:
const gcloud = require('gulp-gcloud-publish');
function publish() {
return src(dest + '/*/app.*')
.pipe(gcloud({
//options
}));
}
This works fine, but it uploads the files sequentially. There are a few of them, so this takes a little while and I'd rather be able to upload them all in parallel sets.
I tried instead to glob it myself:
const glob = require('glob');
const gcloud = require('gulp-gcloud-publish');
const { src } = require('gulp');
function publish() {
const files = glob.sync(path);
let stream;
files.forEach(function(file) {
stream = src(file)
.pipe(gcloud({
//...
}));
return stream;
});
}
This worked great - the task still runs sequentially, but the uploads start without waiting on the last to complete. However, for whatever reason, while glob captures the relative path to the file, when I put that file path into src, gulp drops it down to just the file name itself (as seen if I tap the pipe before gcloud).
So I tried setting the base option instead:
const glob = require('glob');
const gcloud = require('gulp-gcloud-publish');
const { src } = require('gulp');
function publish() {
const files = glob.sync(path);
let stream;
files.forEach(function(file) {
stream = src(file, {base: '.')
.pipe(gcloud({
//...
}));
return stream;
});
}
Unfortunately, now src captures the absolute path to the file instead of just the file and its relative parent. I also just noticed that my glob is removing periods from file names that contain more than one (e.g. app.map.js is turning into appmap.js), so that's not right either.
Scrapping the last two attempts then, is there any way to run the pipe of an operation that otherwise works perfectly fine and run the pipes within a task in parallel?

Check if file contains a specific string in GULP

I am attempting to use GULP4 to compress a series of HTML and PHP files. A problem I am running into is some of the files contain a <pre> tag. I do not want to compress those files because it would mess up that file. Is there a way using GULP I can evaluate if a file contains the string <pre> and if it does, avoid running compression on that file?
Here is my relevant code:
const gulp = require('gulp');
const {src, series, parallel, dest} = require('gulp');
const GulpReplace = require('gulp-replace');
function no_2_spaces_purchasingdemand_php()
{
console.log("no 2 spaces purchasingdemand_php")
return gulp.src
(
'dist/purchasingdemand/**/*.php'
, { base: "./" }
)
.pipe
(
GulpReplace(' ','☺☻')
)
.pipe
(
GulpReplace('☻☺','')
)
.pipe
(
GulpReplace('☺☻',' ')
)
.pipe(gulp.dest('./'))
}
exports.default = series(no_2_spaces_purchasingdemand_html)
I don't know what you are using to compress files, but here is a general example:
const gulp = require('gulp');
const filter = require('gulp-filter');
const minify = require('gulp-htmlmin');
gulp.task("preFilterTask", function () {
// return true if want the file in the stream
const preFilter = filter(function (file) {
let contents = file.contents.toString();
return !contents.match('<pre>');
});
return gulp.src("./*.html")
.pipe(preFilter)
.pipe(minify({ collapseWhitespace: true }))
.pipe(gulp.dest('filtered'));
});
gulp.task('default', gulp.series('preFilterTask'));
gulp-htmlmin by itself - for html files only - will not minify the <pre>...</pre> portion of an html file. So if you use gulp-htmlmin for html minification, you don't need to filter out those with <pre> tags.
I still showed how to filter based on file content using the gulp-filter plugin. It can access each file's contents. Return false from the filter function if you do not want that file to pass to the next pipe.

overwrite all files from one folder to another folder with gulp

I already have my method that compresses the content of the files with gulp-minify-css in a temporary folder which I hope to later delete with gulp if possible but I don't see how to replace the files first, I have:
var revReplace = require('gulp-rev-replace'); // -> this folder is not recognized
gulp.task('revrep', () => {
return gulp.src('app/Styles/CssArqMincss')
.pipe(gulp.dest('app/Content/CSSArq/'));
})
and how can I later delete the folder /Styles/CssArqMincss?
Thanks
To delete files from folder location, you can use this task and adapt it.
const { src, task } = require( 'gulp' );
const clean = require("gulp-clean");
const logger = require('node-color-log');
function cleanFolderTask() {
const yourPathRoot = "pathToYourFolder"; //I would recommend using config file to store paths, such as : config.path.artifact.root;
logger.color('yellow').log(`Cleaning ${yourPathRoot}`);
return src(yourPathRoot ,{allowEmpty: true},{read: false}).pipe(clean({force:true}));
};
const cleanFolderTask= task('clean:folder', cleanFolderTask);
exports.cleanFolderTask= cleanFolderTask;
To copy from one folder to another one, I would also use the previous task to first clean the destination and then :
const { src, dest, task } = require( 'gulp');
const logger = require('node-color-log');
function copyFilesTask(callback) {
let filesLoc = "path/to/your/files";
let filesDest = "path/to/destination"; // I would recommend using config file to store paths, such as : config.path.artifact.files and config.path.solution.files;
logger.color('yellow').log(`Copy ${filesDest }`);
src(`${filesLoc}/**/*`)
.pipe(dest(filesDest),
callback());
};
const copyFiles = task('copy:files', copyFilesTask);
exports.copyFiles = copyFiles;

Gulp: copy file to multiple folders starting with specific string

I'm working to copy a file style.scss from specific directory to multiple folders that start with skin-.
In fact, i don't know how to tell gulp to choose folders that start with this string skin-.
Here is my gulp code:
// Copy Files
gulp.task( "copyFiles" , function() {
return gulp.src( "app/scss/style.scss" )
.pipe( gulp.dest( "app/scss/skins/skin-*" ) );
});
At command prompt, it says that the task is running but with no result.
I have searched a lot around for that, but i didn't find a method. I found this question here which near to my question context, but it didn't help! Gulp copy single file (src pipe dest) with wildcarded directory
Modifying only slightly #davidmdem's answer at saving to multiple destinations:
const gulp = require("gulp");
const glob = require("glob");
const destinationFolders = glob.sync("app/scss/skins/skin-*");
gulp.task('copyFiles', function () {
var stream = gulp.src("app/scss/style.scss");
destinationFolders.forEach(function (skinFolder) {
stream = stream.pipe(gulp.dest(skinFolder));
});
return stream;
});
You cannot put a glob into gulp.dest as you are trying in your question.

Gulp-header plus merge-stream results in a glitch?

Here’s some puzzling behavior.
I want to create a gulp task that will 1) build js-files into one file using gulp-requirejs-optimize and place it into the build directory, 2) copy a couple of config js-files into relevant subfolders of the build directory, and 3) add a header to these files.
Here’s how I am attempting to do this:
In a banner.js file, I create a header using gulp-header:
var header = require('gulp-header');
var bannerTemplate = [
'/**',
' * Hello ${name}',
' */'
].join('\n');
var banner = header(bannerTemplate, {name: 'world'});
module.exports = banner;
Then, in the file that is building javascript, I do the following:
var gulp = require('gulp');
var merge = require('merge-stream');
var requirejsOptimize = require('gulp-requirejs-optimize');
var banner = require('./banner.js');
gulp.task('js:build:test', function() {
// this is the entry point for our javascript files;
// will produce a single main.js file
var jsEntry = path.join(global.paths.jsDirectory, 'main.js');
var options = {
baseUrl: global.paths.jsDirectory,
mainConfigFile: path.join(global.paths.jsDirectory,
'libs/customized/requirejs/require.config.js'),
preserveLicenseComments: false
};
var jsOutput = path.join(global.paths.buildDirectory, 'js');
// I am also copying the require.js library and its customization; don't ask why
var jsForCopy = [
path.join(global.paths.jsDirectory, 'libs/vendors/requirejs/require.js'),
path.join(global.paths.jsDirectory, 'libs/customized/requirejs/**/*.js')
];
var requirejsOptimized = gulp.src(jsEntry)
.pipe(requirejsOptimize(options))
.pipe(banner)
.pipe(gulp.dest(jsOutput));
var copiedJS = gulp.src(jsForCopy, {base: global.paths.root})
.pipe(banner) // having this line will cause a glitch
.pipe(gulp.dest(global.paths.buildDirectory));
return merge(requirejsOptimized, copiedJS);
});
So here is where it is getting interesting. If I pipe through my banner only the stream that is building the main.js file (var requirejsOptimized in my code sample), then everything is fine — I get a build folder with correct files and correct structure:
if, however, I also pipe through the banner the stream that is copying other js files (var copiedJS in my code sample), then the structure of my build directory gets all jumbled up:
(notice the duplication of main.js and the absence of the libs folder with its subfolders)
So my question is, am I doing something obviously wrong with my gulp task here? Is it an expected result or is it a glitch of some kind?
I wouldn't reuse the banner stream in both pipelines. Both pipelines are writing to and reading from the same stream. That is why the output is weird.
Instead, use a new banner stream for each pipeline:
Change banner.js so it exports a function that creates a new banner stream
module.exports = function createBannerStream() {
return header(bannerTemplate, {name: 'world'});
};
In your main file invoke the function when you need a banner stream
var requirejsOptimized = gulp.src(jsEntry)
.pipe(requirejsOptimize(options))
.pipe(banner()) // <-- note the function call here
.pipe(gulp.dest(jsOutput));
var copiedJS = gulp.src(jsForCopy, {base: global.paths.root})
.pipe(banner()) // <-- note the function call here
.pipe(gulp.dest(global.paths.buildDirectory));