이미지 스프라이트 자동화하기

gulp로 이미지 스프라이트를 자동화하는 task를 구성해봤습니다.  아래 샘플은 여러 개의 스프라이트를 만들 수 있고 레티나 대응도 가능하기 때문에 프로젝트를 효율적으로 관리할 수 있습니다.

{
  "name": "sprite",
  "scripts": {
    "start": "gulp default"
  },
  "devDependencies": {
    "del": "^2.2.2",
    "gulp": "^3.9.1",
    "gulp-sass": "^2.3.2",
    "gulp-sass-glob": "^1.0.8",
    "gulp-watch": "^4.3.11",
    "gulp.spritesmith-multi": "^3.1.0",
    "merge-stream": "^1.0.1",
    "run-sequence": "^1.2.2"
  }
}
var gulp = require('gulp'),
	runSequence = require('run-sequence'),
	merge = require('merge-stream'),
	watch = require('gulp-watch'),
	sass = require('gulp-sass'),
	sassGlob = require('gulp-sass-glob'),
	spritesmith = require('gulp.spritesmith-multi'),
	del = require('del');

/* ---------------------------------------------------------------------------------- */

// Clean Sprite
gulp.task('clean-sprite', function() {
	return del('./dist/img/sprite');
});

// 자동 스프라이트
gulp.task('auto-sprite', function() {
	var opts = {
		spritesmith: function (options, sprite, icons){
			options.imgPath =  `../img/sprite/${options.imgName}`;
			options.cssName = `_${sprite}-sprite.scss`;
			options.cssTemplate = null;
			options.cssSpritesheetName = sprite;
			options.padding = 10;
			options.cssVarMap =  function(sp) {
				sp.name = `${sprite}-${sp.name}`;
			};

			return options;
		}
	};
	var spriteData = gulp.src('./src/img-sprites/**/*.png').pipe(spritesmith(opts)).on('error', function (err) {
		console.log(err)
    });
	
	var imgStream = spriteData.img.pipe(gulp.dest('./dist/img/sprite'));
	var cssStream = spriteData.css.pipe(gulp.dest('./src/scss/vendors'));

	return merge(imgStream, cssStream);
});

// 스프라이트 and SASS
gulp.task('sprite-and-sass', function() {
	runSequence('clean-sprite', 'auto-sprite', 'sass');
});

// sass
gulp.task('sass', function() {
	return gulp.src('./src/scss/**/*.scss')

		// use glob imports
        .pipe(sassGlob())

		// SASS
		.pipe(sass({
			errLogToConsole: true,
			outputStyle: 'compressed' // nested, expanded, compact, or compressed.
		}).on('error', sass.logError))

		// css 배포
		.pipe(gulp.dest('./dist/css'));
});
 
gulp.task('watch', function() {
	watch(['./src/scss/*.scss', './src/**/*.scss'], function() {
		gulp.start('sass');
	});
	watch(['./src/img-sprites/**/*'], function() {
		gulp.start('sprite-and-sass');
	});
});
 
gulp.task('default', [
	'sprite-and-sass',
	'watch'
]);
//
// COMMON.SCSS
// --------------------------------------------------

// Vendor
@import './vendors/*-sprite.scs';	// 아이콘 스프라이트 SCSS (gulp.spritesmith 모듈이 자동생성)

.test {
	@include sprite($icon-checkbox-on);
}

샘플 프로젝트의 디렉토리 구조

default task를 실행하면 src/img-sprites의 각 폴더 단위로 스프라이트를 생성하게 됩니다. 생성된 스프라이트 이미지는 dist/img/sprite에 생성되고, scss파일은 src/vendors으로 저장됩니다. scss파일을 확인하면 각 이미지마다 다양한 변수가 만들어져 있기 때문에 css작성시 참조할 수 있습니다.

@2x 파일명의 이미지를 추가하여 레티나 대응을 위한 한 벌의 이미지 세트를 사용할 수도 있습니다. 레티나 세트의 scss에는 retina-sprite등의 mixin이 추가됩니다. 또는 2x, 3x의 고해상도 이미지만 사용하면서 각종 변수를 참조하여 1/2, 1/3으로 나누는 mixin을 만들어도 됩니다.

그리고 gulp-watch 모듈로 이미지폴더를 감시해서 작업중에 이미지를 추가하거나 삭제하면 스프라이트를 다시 생성한 후 scss를 컴파일하도록 되어있습니다.