svg形式のオリジナルiconfontのmixin作成

この記事、Gulp4でのビルドを前提として書いています。

#やりたかったこと
- 独自のIconFont用のSVGを、特定のディレクトリに追加すると勝手にビルド実行！
    - watchタスクは書いてません…🙇‍♂️
- SVGが追加されるたびに、IconFont用scssのmixinが更新！
- mixin作成による、scss記述の作業軽量化！

#サンプルを使っても上手くいかず苦戦したところ
- content要素が文字化けして、上手く出力されなかった！

#参考記事
- [オリジナルアイコンフォントを作成する](https://qiita.com/hiron712/items/b121ee42d19edbfaaccd)
- [アイコンフォントをscssの配列とmixinでスッキリまとめてみよう](https://qiita.com/niever66/items/108b7ab09bcbbe583d95)

# ビルド環境

## node -v
- v8.16.2

## npm -v
- 6.14.7


## gulp -v
- CLI version: 2.3.0
- Local version: 4.0.2

## npm module
- gulp-iconfont
- gulp-consolidate
- gulp-rename

```gulpfile.js

const iconfont		= require('gulp-iconfont');
const consolidate	= require('gulp-consolidate');
const rename		= require('gulp-rename');
	
// icon font
const filename = 'icon';
function fontBuild(cb) {
	return gulp.src('src/icon/svg/*.svg')
	.pipe(iconfont({
         fontName: filename,
         formats: ['ttf', 'eot', 'woff','woff2' , 'svg' ]
		}))
	.on('glyphs', function(glyphs, options) {

        let consolidateOptions = {
            glyphs: glyphs,
            fontName: filename,
            fontPath: 'fonts/',
            className: 'ico'
        }

        gulp.src('src/icon/template/iconfont.scss')
            .pipe(consolidate('lodash', consolidateOptions))
            .pipe( rename( { basename: '_iconfont' , extname: '.scss'}))
            .pipe(gulp.dest('src/sass/core/'));

        gulp.src('src/icon/template/css.ejs')
            .pipe(consolidate('lodash', consolidateOptions))
            .pipe(rename( { basename: filename , extname: '.css'} ) )
            .pipe(gulp.dest('src/icon/sample/'));

        gulp.src('src/icon/template/html.ejs' )
            .pipe(consolidate( 'lodash', consolidateOptions))
            .pipe( rename( { basename: filename , extname: '.html'}))
            .pipe( gulp.dest('src/icon/sample/') );
    })
	.pipe(gulp.dest('src/icon/sample/fonts/'))
	.pipe(gulp.dest('dest/fonts/'));
	cb();
}

~ 省略 ~

```

taskの実行処理はお好みで・・・
わたしは、**_iconfont.scss** がsrc/sass/coreフォルダに出力された後、scssのコンパイルを走らせています。

```iconfont.scss
$iconFont-path: "<%= fontPath %>" !default;

@font-face {
	font-family: "<%= fontName %>";
	src: url('<%= fontPath %><%= fontName %>.eot?64h6xh');
	src: url('<%= fontPath %><%= fontName %>.eot?64h6xh#iefix') format('embedded-opentype'),
		 url('<%= fontPath %><%= fontName %>.ttf?64h6xh') format('truetype'),
		 url('<%= fontPath %><%= fontName %>.woff?64h6xh') format('woff'),
		 url('<%= fontPath %><%= fontName %>.svg?64h6xh#<%= fontName %>') format('svg');
	font-weight: normal;
	font-style: normal;
}

//アイコンを配列で指定
$icons:( <% _.each(glyphs, function(glyph) { %>
	<%= className %>-<%= glyph.name %> : "<%= glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() %>", <% }); %>
) !default;

//mixinを作る。アイコンの種類と、疑似要素の位置を引数で渡す。
@mixin icon($icon: false, $position: before){

  @if $position == both {
    $position: 'before, &:after'
  }
  
 &:#{$position}{
    @if $icon{
      content: #{'"\\' + map-get($icons, $icon) + '"'};
      font-family: '<%= fontName %>';
      speak: none;
      font-style: normal;
      font-weight: normal;
      font-variant: normal;
      text-transform: none;
      line-height: 1;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
  }
  @content;
}
```
上記、iconfont.scssの出力結果が以下になります。

```_iconfont.scss
$iconFont-path: "fonts/" !default;

@font-face {
	font-family: "icon";
	src: url('fonts/icon.eot?64h6xh');
	src: url('fonts/icon.eot?64h6xh#iefix') format('embedded-opentype'),
		 url('fonts/icon.ttf?64h6xh') format('truetype'),
		 url('fonts/icon.woff?64h6xh') format('woff'),
		 url('fonts/icon.svg?64h6xh#icon') format('svg');
	font-weight: normal;
	font-style: normal;
}

//アイコンを配列で指定
$icons:( 
	ico-hogehoge1 : "EA01", 
	ico-hogehoge2 : "EA02", 
) !default;

//mixinを作る。アイコンの種類と、疑似要素の位置を引数で渡す。
@mixin icon($icon: false, $position: before){

  @if $position == both {
    $position: 'before, &:after'
  }
  
 &:#{$position}{
    @if $icon{
      content: #{'"\\' + map-get($icons, $icon) + '"'};
      font-family: 'icon';
      speak: none;
      font-style: normal;
      font-weight: normal;
      font-variant: normal;
      text-transform: none;
      line-height: 1;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
  }
  @content;
}
```

mixinでは、contentの呼び出し部分をこんな書き方にしてます。
> content: #{'"\\' + map-get($icons, $icon) + '"'};

```design.scss
.hogehoge1 {
  @include icon(ico-hogehoge1, before);
}
.hogehoge2 {
  @include icon(ico-hogehoge2, after);
}
```
mixinを上記の方法で呼び出し、コンパイル後のcssが以下になりますが
**content: "\EA01";** となって文字化け（お豆腐化）を起こしていません。

```design.css
@font-face {
  font-family: "icon";
  src: url("fonts/icon.eot?64h6xh");
  src: url("fonts/icon.eot?64h6xh#iefix") format("embedded-opentype"), url("fonts/icon.ttf?64h6xh") format("truetype"), url("fonts/icon.woff?64h6xh") format("woff"), url("fonts/icon.svg?64h6xh#icon") format("svg");
  font-weight: normal;
  font-style: normal;
}

.hogehoge1:before {
  content: "\EA01";
  font-family: 'icon';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.hogehoge2:after {
  content: "\EA02";
  font-family: 'icon';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

```

sampleのhtml/cssは有っても無くても良いと思いますが
作成したアイコンフォントの一覧があった方が便利です。

sampleソース用のejsは、ほぼ参考サイトのままのソースを使わせていただきました！

```css.ejs
@font-face {
    font-family: "<%= fontName %>";
    src: url('<%= fontPath %><%= fontName %>.eot');
    src: url('<%= fontPath %><%= fontName %>.eot?#iefix') format('eot'),
        url('<%= fontPath %><%= fontName %>.woff') format('woff'),
        url('<%= fontPath %><%= fontName %>.ttf') format('truetype'),
        url('<%= fontPath %><%= fontName %>.svg#<%= fontName %>') format('svg');
    font-weight: normal;
    font-style: normal;
}
[class^="<%= className %>-"]:before, [class*=" <%= className %>-"]:before {
    display: inline-block;
    font-family: "<%= fontName %>";
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
.<%= className %>-lg {
    font-size: 1.3333333333333333em;
    line-height: 0.75em;
    vertical-align: -15%;
}
.<%= className %>-2x { font-size: 2em; }
.<%= className %>-3x { font-size: 3em; }
.<%= className %>-4x { font-size: 4em; }
.<%= className %>-5x { font-size: 5em; }
.<%= className %>-fw {
    width: 1.2857142857142858em;
    text-align: center;
}
<% _.each(glyphs, function(glyph) { %>.<%= className %>-<%= glyph.name %>:before { content: "\<%= glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() %>" }
<% }); %>


/**/
[class^="af-<%= className %>-"]:after, [class*=" af-<%= className %>-"]:after {
    display: inline-block;
    font-family: "<%= fontName %>";
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
.<%= className %>-lg {
                     font-size: 1.3333333333333333em;
                     line-height: 0.75em;
                     vertical-align: -15%;
                 }
.af-<%= className %>-2x { font-size: 2em; }
.af-<%= className %>-3x { font-size: 3em; }
.af-<%= className %>-4x { font-size: 4em; }
.af-<%= className %>-5x { font-size: 5em; }
.af-<%= className %>-fw {
                     width: 1.2857142857142858em;
                     text-align: center;
                 }
<% _.each(glyphs, function(glyph) { %>.af-<%= className %>-<%= glyph.name %>:after { content: "\<%= glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() %>" }
<% }); %>
```

```html.ejs
<html>
  <head>
    <title><%= fontName %></title>
    <link href="<%= fontName %>.css" rel="stylesheet">
    <style>
      body { font-family: Gill Sans; text-align: center; background: #f7f7f7 }
      body > h1 { color: #666; margin: 1em 0 }
      .glyph { padding: 0 }
      .glyph > li { display: inline-block; margin: .3em .2em; width: 5em; height: 6.5em; background: #fff; border-radius: .5em; position: relative }
      .glyph > li span:first-child { display: block; margin-top: .1em; font-size: 4em; }
      .glyph-name { font-size: .8em; color: #999; display: block }
      .glyph-codepoint { color: #999; font-family: monospace }
    </style>
  </head>
  <body>
    <h1><%= fontName %></h1>
    <ul class="glyph"><% _.each(glyphs, function(glyph) { %>
      <li>
        <span class="<%= className %> <%= className %>-<%= glyph.name %>"></span>
        <span class="glyph-name"><%= className %>-<%= glyph.name %></span>
        <span class="glyph-codepoint"><%= glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() %></span>
      </li><% }); %>
    </ul>
  </body>
</html>
```