Search code examples
javascriptsvgnpmsprite-sheetgrunt-svgstore

How to concatenate relative path or generate unique identifier svg contained in nested folders?


I have many icons exported by "Figma" in a folder structure, I have used grunt-svgstore to generate the sprite sheet but I'm getting duplicated ids in the result.
I have tried with "allowDuplicateItems: false" and "setUniqueIds: true" but it doesn't work.

Folder structure:
-icons
--arrow
---arrow-left
----scale.svg
---arrow-right
----scale.svg
--checkbox
---active.svg
---inactive.svg
--chevron
---left-chevron
----scale.svg
---right-chevron
----scale.svg
--etc.

Grunt file JS:

module.exports = function(grunt) {
grunt.initConfig({
    svgstore: { 
        options: {
            formatting : {
                indent_size : 2
            },
            includeTitleElement: false,
            preserveDescElement: false,
            allowDuplicateItems: false,
            setUniqueIds: true
        },
        default: {
            files: {
                'includes/defs.svg': ['icons/**/*.svg',]
            },
        },
    }
});  
grunt.loadNpmTasks('grunt-svgstore');  
};

Expected result based on relative path

<svg>
  <symbol viewBox="0 0 32 32" id="arrow-arrow-left-scale">
    ...
  </symbol>
  <symbol viewBox="0 0 32 32" id="arrow-arrow-right-scale">
    ...
  </symbol>
</svg>

Actual result:

<svg>
  <symbol viewBox="0 0 32 32" id="scale">
    ...
  </symbol>
  <symbol viewBox="0 0 32 32" id="scale">
    ...
  </symbol>
</svg>

Solution

  • I have found another tool which allows me to do what I needed.

    Sharing solution:

    const zipName = 'icons.zip';
    //Command: gulp default
    const spriteFileName = 'icons_sprite';
    const gulp = require('gulp');
    const svgstore = require('gulp-svgstore');
    const rename = require('gulp-rename');
    const path = require('path');
    const admZip = require('adm-zip');
    const rimraf = require('rimraf');
    const fs = require('fs');
    
    gulp.task('default', function() {
      var zip = new admZip(zipName);
      zip.extractAllTo('./icons_sources/', false, true);
      return gulp
        .src('icons_sources/**/*.svg', {base: 'icons_sprite'})
        .pipe(
          rename(function(file) {
            var name = file.dirname.split(path.sep);
            if (file.basename === 'scale') {
              name = name.filter((n) => n !== '.' && n !== '..' && n !== 'icons_sources');
              file.basename = name.join('-');
            } else {
              name = name.filter((n) => n !== '.' && n !== '..' && n !== 'icons_sources');
              if (file.basename.search(/\d+x\d+/) >= 0) {
                file.basename = 'S' + file.basename.toUpperCase();
              }
            }
          })
        )
        .pipe(svgstore())
        .pipe(gulp.dest('src/assets/sprites'))
        .on('finish', () => {
          rimraf.sync('icons_sources');
          fs.unlinkSync(zipName);
        });
    });