(2015.1.20追記)
gulpfile.jsのパスが間違えていたので、修正しました。
Gulpの導入自体がまだの人は、こちらをどうぞ。
gulp.spritesmithとgulp-svg-symbols
CSSスプライトには、gulp.spritesmithを使用しました。
SVGスプライトは、gulp-svg-spritesの方が良さそうだったのですが、Windowsでうまくインストールできなかったので、gulp-svg-symbolsにしました。
twolfson/gulp.spritesmith · GitHub
Hiswe/gulp-svg-symbols · GitHub
それぞれインストールしましょう。
CSSスプライト
npm install gulp.spritesmith --save-dev
SVGスプライト
npm install gulp-svg-symbols --save-dev
エンジンを入れる
gulp.spritesmithを使うには、画像結合するためのエンジンが必要になります。
以下のどれかをインストールしなくてはいけません。
- pngsmith
- phantomjs
- canvas
- gm (Graphics Magick / Image Magick)
私は、WindowsとMacで簡単にインストールできたgm (Graphics Magick / Image Magick)を選びました。
WindowsのGraphics Magick
ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/windows/
MacのGraphics Magick
brew install graphicsmagick
ディレクトリを分ける
スプライト系のプラグインは、画像を統合し、それに対応したCSSを同時に作成します。
普通に実装すると、画像とCSSを1つだけ作ることになります。
しかし、こちらの解説のようにwatchを利用することで、ディレクトリ単位で、各ファイルを作ることができます。
gulp.spritesmithを便利にカスタマイズ – to-R
私の場合、watchではなく、他のタスクと同じように名前を付けたかったので、globbyというプラグインを使いました。
gulp-svg-symbolsの設定
gulp.spritesmithと違って、gulp-svg-symbolsには、ファイルによって出力場所を変えたり、名前を変更する機能がありません。
公式サイトにもある通り、下記のプラグインを入れて それぞれ対応します。
条件を設定して、処理を分岐
npm install gulp-if --save-dev
名前を変更
npm install gulp-rename --save-dev
出力ルールについて
この辺りは、好みで良いと思いますが、自分ルールで設定してみます。
CSSスプライト
app/sprite_img/にスプライト名になるディレクトリを作成し、スプライトにしたい画像ファイルを入れます。
出力された画像ファイルは、app/img/に入れます。
CSSファイルは、SASSにして、app/css/に入れて、メインのCSSへインポートすることにします。
インポートされたファイルは、そのまま使用することはないので、アンダーバーをつけて、納品用のディレクトリに入らないようにします。
SVGスプライト
app/sprite_svg/にスプライト名になるディレクトリを作成し、スプライトにしたいSVGファイルを入れます。
SVGスプライトは、インラインで読み込むと使える機能が増えるため、appディレクトリの外にある、inc/svg/に入れます。
gulp-file-includeの機能で、使用したいhtmlファイル内のbody直下に読み込みます。
使用するhtml内
@@include('inc/svg/img.svg')
このCSSファイルも、SASSにし、app/css/に入れて、メインのCSSへインポートします。
同じように、納品用のディレクトリに入らないようにします。
SVGをインラインでの機能を使用しない場合は、CSSスプライトと同じルールの出力で良いでしょう。
gulpfile.js
俺だけのGulpにも使用したものを含めて、記述するとこんな感じになりました。
細かく変わっていますが、気にしないでください。
gulpfile.js
var gulp = require('gulp'), coffee = require('gulp-coffee'), sass = require('gulp-sass'), autoprefixer = require('gulp-autoprefixer'), browser = require('browser-sync'), plumber = require("gulp-plumber"), gifsicle = require('imagemin-gifsicle'), jpegtran = require('imagemin-jpegtran'), optipng = require('imagemin-optipng'), svgo = require('imagemin-svgo'), fileinclude = require('gulp-file-include'), prettify = require('gulp-prettify'), cssbeautify = require('gulp-cssbeautify'), jsprettify = require('gulp-jsbeautifier'), changed = require('gulp-changed'), del = require('del'), csscomb = require('gulp-csscomb'), spritesmith = require("gulp.spritesmith"), svgSymbols = require('gulp-svg-symbols'), gulpif = require('gulp-if'), rename = require("gulp-rename"), globby = require('globby') ; var paths = { base :'/project/', copy :['app/**/base.css'], scss :['app/**/*.scss','!app/**/_*.scss'], css :['app/**/*.css','!app/**/base.css'], js :['app/**/*.js'], coffee:['app/**/*.coffee'], html :['app/**/*.html'], image :['app/**/img/**'], spriteImg:['app/**/sprite_img/**/*.{png,gif,jpg}'], spriteSvg :['app/**/sprite_svg/**/*.svg'], distSvg:'inc/svg', appCss:'app/css', appImg:'app/img', dist :'./dist' }; function spriteWatchSvg(path){ var filePath = path.match(/^(.+\/)(.+?)(\/.+?\..+?)$/); return gulp .src(filePath[1] + filePath[2] + '/*.svg')//(2015.1.20修正 .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(svgSymbols()) .pipe(rename({ basename: filePath[2] })) .pipe(gulpif( /[.]css$/, rename({ basename: '_' + filePath[2], extname: '.scss' }))) .pipe(gulpif( /[.]svg$/, gulp.dest(paths.distSvg))) .pipe(gulpif( /[.]scss$/, gulp.dest(paths.appCss))) .pipe(gulpif( /[.]html$/, gulp.dest(paths.distSvg))); } gulp.task('spriteSvg', function(){ globby(paths.spriteSvg, function (err, paths) { paths.forEach(function(path){ spriteWatchSvg(path); }); }); }); function spriteWatchImg(path){ var filePath = path.match(/^(.+\/)(.+?)(\/.+?\..+?)$/); var spriteData = gulp.src(filePath[1] + filePath[2] + '/*.{png,gif,jpg}') .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(spritesmith({ imgName: filePath[2] + '.png', cssName: '_' + filePath[2] + '.scss', imgPath: '../img/' + filePath[2] + '.png', padding: 10, cssFormat: 'scss', engine:'gm' })); spriteData.img.pipe(gulp.dest(paths.appImg)); spriteData.css.pipe(gulp.dest(paths.appCss)); return spriteData; } gulp.task('spriteImg', function(){ globby(paths.spriteImg, function (err, paths) { paths.forEach(function(path){ spriteWatchImg(path); }); }); }); gulp.task('copy', function() { return gulp .src(paths.copy) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(fileinclude({basepath: paths.base})) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('server', function(cb) { browser({server: {baseDir: paths.dist}},cb); }); gulp.task('image', function() { return gulp .src(paths.image) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(gifsicle()) .pipe(jpegtran()) .pipe(optipng()) .pipe(svgo()) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('sass', function() { return gulp .src(paths.scss) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(fileinclude({basepath: paths.base})) .pipe(sass({ errLogToConsole: true, sourceComments: 'map' })) .pipe(autoprefixer()) .pipe(csscomb()) .pipe(cssbeautify()) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('css', function() { return gulp .src(paths.css) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(fileinclude({basepath: paths.base})) .pipe(autoprefixer()) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('coffee', function() { return gulp .src(paths.coffee) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(fileinclude({basepath: paths.base})) .pipe(coffee()) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('js', function() { return gulp .src(paths.js) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(fileinclude({basepath: paths.base})) .pipe(jsprettify()) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('html', function() { return gulp .src(paths.html) .pipe(plumber()) .pipe(changed(paths.dist)) .pipe(fileinclude({basepath: paths.base})) .pipe(prettify()) .pipe(gulp.dest(paths.dist)) .pipe(browser.reload({stream:true})); }); gulp.task('clean', function(cb) { del(paths.dist, cb); }); gulp.task('watch', function() { gulp.watch(paths.copy,['copy']); gulp.watch(paths.spriteImg,['spriteImg']); gulp.watch(paths.spriteSvg,['spriteSvg']); gulp.watch(paths.scss,['sass']); gulp.watch(paths.css,['css']); gulp.watch(paths.coffee,['coffee']); gulp.watch(paths.html,['html']); gulp.watch(paths.js,['js']); gulp.watch(paths.image,['image']); }); gulp.task('build', ['clean'], function(){ gulp.start('create'); }); gulp.task('create', ['copy','spriteImg','spriteSvg','sass','css','coffee','html','js','image'],function(){ gulp.start('server'); }); gulp.task('default', ['build','watch']);
オレオレGulpになってしましましたが、誰かの参考のなれば幸いです。
そんじゃーねー。
コメント