アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

gulp でアイコン フォント生成

今日の昼休み、はてブを見ていたら以下の記事がホットエントリーに入っていた。

アイコン フォント生成に IcoMoon を利用しているのだけど gulp で同等の処理を実現可能なら SVG とビルド処理をリポジトリで一元管理できて便利だ。というわけで自分でも試してみる。

gulp-iconfont

冒頭にあげた記事ではアイコン フォントの生成に gulp-iconfont-css を利用しているが gulp.js plugin registry の検索だとヒットしない。調べてみたところ、このプラグインはブラックリストに入ってしまったようだ。リストには代替として gulp-iconfont が挙げられていたので今回はこちらを採用する。

プロジェクト構成

プロジェクト構成は以下のようにしてみた。

/
├ package.json
├ gulpfile.js
└ src/
   └ icons/
      ├ template.css
      ├ template.html
      ├ icons.idraw
      └ *.svg

template.css はアイコン フォントを利用するための CSS を生成するために参照されるテンプレートで、HTML はアイコン一覧を確認するためのページ生成用テンプレート。

icons.idraw は iDraw 用ファイル。今回のサンプルで使用する SVG アイコンは私がこのアプリで作成した。すべて単一レイヤーで完結する簡単なピクトグラムなのでレイヤー単位で SVG ファイルを書き出した。このようにするとレイヤー名をファイルに付けて出力される。

※2019/1 現在、アプリ名称は Graphic に変更されている。このアイコンは当時のもので今は異なる。

グラフィック アプリ固有ファイルをリポジトリに含めるかは迷うところ。なんとなく変更の多いバイナリを入れるのは躊躇してしまう。とはいえ SVG だけ入れても生成元が失われたら取り戻すのが困難になるのだし KB 〜 数 MB ぐらいならリポジトリ管理してもよいかな。

プロジェクトのルート直下で npm install と gulp ビルドを実行すると、以下のような構成になる。

/
├ package.json
├ gulpfile.js
├ node_modules/
│  └ node.js パッケージ
└ src/
   ├ icon-sample.html
   ├ css/
   │  └ icon.css
   └ fonts/
   │  ├ icon.eot
   │  ├ icon.svg
   │  ├ icon.ttf
   │  └ icon.woff
   └ icons/
      ├ template.css
      ├ template.html
      ├ icons.idraw
      └ *.svg

/src/icons 内の SVG ファイルを参照して /src/fonts にアイコン フォントを出力。その際 template.css から src/css/icon.csstemplate.html から src/icon-templ.html もあわせて生成。

gulp タスク定義

gulp のタスク定義と CSS、HTML テンプレートは以下のプロジェクトを参考にした。

CSS は更に IcoMoon を踏襲、HTML のアイコン一覧は配色やサイズなどを変更。gulp タスクは以下のように定義。

var gulp = require( 'gulp' );
var $    = require( 'gulp-load-plugins' )();

/**
 * SVG からアイコンフォントを生成します。
 *
 * @return {Object} ストリーム。
 */
gulp.task( 'font', function() {
    var fontName = 'icon';

    return gulp.src( 'src/icons/*.svg' )
        .pipe( $.iconfont( { fontName: fontName } ) )
            .on( 'codepoints', function( codepoints ) {
                var options = {
                    className: fontName,
                    fontName:  fontName,
                    fontPath:  '../fonts/',
                    glyphs: codepoints
                };

                // CSS
                gulp.src( 'src/icons/template.css' )
                    .pipe( $.consolidate( 'lodash', options ) )
                    .pipe( $.rename( { basename: fontName } ) )
                    .pipe( gulp.dest( 'src/css' ) );

                // フォント一覧 HTML
                gulp.src( 'src/icons/template.html' )
                    .pipe( $.consolidate( 'lodash', options ) )
                    .pipe( $.rename( { basename: 'icon-sample' }))
                    .pipe( gulp.dest( 'src' ) );
            } )
        .pipe( gulp.dest( 'src/fonts' ) );
} );

/**
 * gulp の既定タスクです。
 */
gulp.task( 'default', [ 'font' ] );

単にアイコン フォントを生成するだけなら on イベントを処理しなくてもよい。on イベントではアイコン フォントの情報とテンプレートをもとに CSS と HTML を生成している。

サンプル

今回の調査で作成したサンプルを以下に公開する。

clone して README.md の Installation に書かれた手順を実行するとアイコン フォント、CSS、アイコン一覧 HTML が生成される。