I am using Gulp to store multiple SVG files into SVG storages which are later reused in order to maximize performance. However, I am now using a rather interesting folder structure where the paths contain interchangeable fixed and dynamic parts.
Let me illustrate. Here is the folder structure I am using. The app/images/products
folder contains folders named productA
, productB
etc. which again contain a subfolder called color-sprites
full of SVG files ready to get combined into a single file and stored in build/images/products/{product name}/color-sprites.svg
.
root/
|_ gulpfile.js
|_ app
|_ images
|_ products
|_ **productA**
|_ color-sprites
|_ sprite1.svg
|_ sprite2.svg
|_ ...
|_ build
|_ images
|_ products
|_ **productA**
|_ color-sprites.svg
Here is a simplified version of the code I am trying to use to accomplish what I need (take note that rename
is an instance of gulp-rename
).
gulp.task('svg-color-sprites', function () {
return gulp.src('app/images/products/**/color-sprites/*.+(svg)')
.pipe(svgMin())
.pipe(svgStore())
.pipe(rename(...))
.pipe(gulp.dest('build/images/'));
});
The problem is that I am not exactly sure how to access current stream parameters in order to construct a target with gulp-rename
because running the gulpfile.js
like this results in taking the first parent element of the path before *
or **
which again results in creating a file called products.svg
in build/images/
. I've seen a couple of examples which use path
to access the basename, relative path etc. but I am not sure how to use it in the context of gulp streams.
The way you're doing things now will create one combined SVG for all of your SVGs, not one combined SVG per product. In fact if you have two files like this:
productA/color-sprites/sprite1.png
productB/color-sprites/sprite1.png
the whole thing will fail because gulp-svgstore
expects file names to be unique.
What you need to do is have one gulp stream per product that each generates one combined SVG.
That means you need to iterate over all the directories in your products
folder, initialize one stream per directory, then merge them so you can return one single stream from your task.
The easiest way to get all the directories in your products
folder is to use glob
and merging streams is made really simple with merge-stream
.
var glob = require('glob');
var merge = require('merge-stream');
var path = require('path');
gulp.task('svg-color-sprites', function () {
return merge(glob.sync('app/images/products/*').map(function(productDir) {
var product = path.basename(productDir);
return gulp.src(productDir + '/color-sprites/*.+(svg)')
.pipe(svgMin())
.pipe(svgStore())
.pipe(gulp.dest('build/images/products/' + product));
}));
});
Since gulp-svgstore
automatically names the resulting combined SVG after the base folder you don't even need to use gulp-rename
at all. The combined SVG file will automatically be named color-sprites.svg
.