LHJ

I'm a FE developer.

gulp-svg-sprite

04 Nov 2020 » node_module

gulp-svg-sprite

async function spriteSvg() {
  const folders = getFolders(`${gulpConfig.src}/img/sprites-svg`);

  let options = {
    spritesmith: (options) => {
      const { folder, gulpConfig } = options;
      return {
        shape: {
          spacing: {
            padding: 4
          },
          id: {
            generator: function (name) {
              return path.basename(name.split(`${gulpConfig.src}/scss/vendor`).join(this.separator), '.svg');
            }
          }
        },
        mode: {
          css: {
            dest: './',
            bust: false,
            sprite: folder + '-svg.svg',
            render:  {
              scss: {
                template: path.join(`${gulpConfig.src}/scss/vendor`, 'sprite-svg-mixins.handlebars'),
                dest: path.posix.relative(`${gulpConfig.src}/img`, path.posix.join(`${gulpConfig.src}/scss`, 'vendor', '_'+folder+'-svg-mixins.scss'))
              }
            }
          }
        },
        variables: {
          spriteName: folder,
          baseName: path.posix.relative(`${gulpConfig.src}/css`, path.posix.join(`${gulpConfig.src}/img`, folder + '-svg')),
          svgToPng: ''
        }
      }
    },
  };

  return folders.map((folder) => {
    return new Promise((resolve) => {
      src(path.join(`${gulpConfig.src}/img/sprites-svg`, folder, '*.svg'))
        .pipe($.sort())
        .pipe($.svgSprite(options.spritesmith({folder, gulpConfig})))
        .pipe(dest(`${gulpConfig.src}/img`))
        .on('end',resolve);
    });
  });
}

테스트해봤는데, 현재 spriteSvg 가 끝나는 시점을 제대로 반환을 못하는 거 같습니다.
현재 코드보시면 .map 메서드로 반복문을 돌려서 gulp.src~~ 코드를 처리하고 있는데,
이게 한번만 반복문을 돌아도 바로 return되어서 실제 끝나는시간보다 더 빨리 끝났다고 gulp에서 인식해버리는 거 같아요.

  1. series(parallel(sprites, spriteSvg), sass)
  2. series(spriteSvg, sprites, sass)

그래서 위와 같이 실행 순서를 병렬로 변경하던지 아니면 spriteSvg를 sprites보다도 빨리 실행하던지하면 에러없이 잘 됩니다.

->그런데 위 방법도 완전한 방법은 아닙니다.
위 방법이 되는 이유는 sprites 함수가 spriteSvg 함수가 실제로 완전히 종료되는 시점보다 더 늦게 종료되어서 그런거같습니다.
즉, 위와 같이 바꿔도 spriteSvg 함수가 실제로 완전히 종료되는 시점이 sprites 함수보다 늦어진다면 (나중에 어떠한이유로..이미지가많아지거나..)
다시 이런 이슈가 발생할 것 같습니다.


즉 이 문제를 완전히 해결하려면 다음과같이 변경해야될것같습니다.

현재 spriteSvg 함수 코드를 보시면 sprite-svg/ 폴더 아래에 (현재는 sprite 폴더만 있지만) spriteA, spriteB, spriteC…. 이렇게 폴더가 여러개 있을수도있다는 상황을 가정하고 짜여진거같아요.
각각의 폴더를 구별하고 각 폴더마다 svg 스프라이트 파일을 만들기 위함인거죠.

그래서 map 메소드를 활용해 반복문을 돌릴수밖에 없었구요.

이를 일단 여러개의 폴더가 있다고 가정하지말고 sprite 폴더 하나만 있다고 생각하고
(현재 라인레포에도 sprite-svg 폴더에 하위폴더로 sprite만있구요)
코드를 변경해 return되는 시점이 실제 함수가 끝나는 시점과 일치시켜야될것 같습니다.

그렇게하니까 잘 되는거 같아요.


sprite 폴더 하나만 있다고 가정하고 변경한 spriteSvg 함수입니다.
물론 이렇게 수정해도 series(sprites, spriteSvg, sass) 이 순서는 지켜줘야됩니다.

function spriteSvg() {
  let options = {
    shape: {
      spacing: {
        padding: 4
      },
      id: {
        generator: function (name) {
          return path.basename(name.split(`${gulpConfig.src}/scss/vendor`).join(this.separator), '.svg');
        }
      }
    },
    mode: {
      css: {
        dest: './',
        bust: false,
        sprite: 'sprite-svg.svg',
        render:  {
          scss: {
            template: path.join(`${gulpConfig.src}/scss/vendor`, 'sprite-svg-mixins.handlebars'),
            dest: path.posix.relative(`${gulpConfig.src}/img`, path.posix.join(`${gulpConfig.src}/scss`, 'vendor', '_sprite-svg-mixins.scss'))
          }
        }
      }
    },
    variables: {
      spriteName: 'sprite',
      baseName: path.posix.relative(`${gulpConfig.src}/css`, path.posix.join(`${gulpConfig.src}/img`, 'sprite-svg')),
      svgToPng: ''
    }
  }

  return gulp.src(`${gulpConfig.src}/img/sprites-svg/**/*.svg`)
    .pipe($.sort())
    .pipe($.svgSprite(options))
    .pipe(gulp.dest(`${gulpConfig.src}/img`))
}