バックエンドエンジニアがタグ書くのが面倒で組んだgulpfile晒します

# はじめに

完全な個人メモです。
フリーでもらった仕事の請求書書くのに、せっかくエンジニアなんだからHTMLをPDFで印刷しようというアイデアではじめました。

バックエンドエンジニアからするとタグを正確に書くにはHTMLは文字数が多すぎる。ということでpugを入れたり色々やってそこそこ気に入ったので、一段落ということで投稿します。
github: [https://github.com/iwamoto-takaaki/invoice_sheet](https://github.com/iwamoto-takaaki/invoice_sheet)

# 導入機能一覧

[packege.json](https://github.com/iwamoto-takaaki/invoice_sheet/blob/master/package.json)

1. gulp関連
    1. "coffeescript": "^2.5.1"      
        gulpfileはcoffeeにした。なくても通るかもしれない。
    1. "gulp": "^4.0.2"     
        仕上がりは読みやすく良かった。が、gulp4使ってみたら書き方が全然違ってしまって混乱を極めた。
    1. "gulp-plumber": "^1.2.1"        
        gulp.watchで自動でコンパイルした際にwatch処理が落ちないようにするのに必須。
    1. "gulp-notify": "^3.2.0"         
        コンソールでなくOSの通知機能にメッセージを飛ばせる。自動コンパイルしていると、コンパイル結果を見逃すことがあるので導入。設定がうまくできていない。
1. html関連
    1. "gulp-pug": "^4.0.1"            
        sass記法に似て、インデントとcssセレクタのような記法でhtmlをかけ、スッキリ見れる。フロントエンド素人の目には、生のタブはややこしすぎる
    1. "gulp-autoprefixer": "^7.0.1"  
        あんまり詳しくない。雰囲気で入れた
    1. "gulp-html-beautify": "^1.0.1" 
        コンパイルしたhtmlのインデントなどを調整してくれる。個人用なので、HTMLはminifyはしない。
1. css関連
    1. "bootstrap": "^4.4.1"           
        cssフレームワーク。あんまり使わんかった。インポートする種類を選択すると小さくできる。課題。
    1. "gulp-sass": "^4.1.0"　　　　　　
        sass記法はインポートの見た目が良いscssよりsassにした。もともとcssに慣れていないのでscssに魅力を感じていない。
1. その他
    1. "gulp-webserver": "^0.9.1"　　　
        htmlyやcssが変更されたらリロードしてくれる。使うとやめられない。

# フォルダ構成

```
.
├── dist
│   ├── css
│   │   └──  style.css
│   └── index.html
├── .gitignore
├── gulpfile.coffee
├── node_modules
├── package-lock.json
├── package.json
└── src
    ├── index.pug
    └── sass
       └──  style.sass
```
srcに書いて、distに出力します。

.gitignoreの設定がめんどくさいのでdistはそのまま管理対象外としています。そのため、imageなどのフォルダが追加された場合、ｓｒｃフォルダ内で管理します。（copy用の設定は面倒ですが・・・）

# gulpfile解説

[gulpfile.coffee](https://github.com/iwamoto-takaaki/invoice_sheet/blob/master/gulpfile.coffee)

簡易記法を導入する言語全般に言えることだけど、どのように書けばどうコンパイルされるた常に意識する必要がある。簡略化しきれてないのでは？という思いがある。

## pug -> html

pubって何って人は、htmlをこの様にかける簡易記法です。
[index.pug](https://github.com/iwamoto-takaaki/invoice_sheet/blob/master/src/index.pug)

```coffeescript
html = ->
  src './src/**/*.pug'
  .pipe plumber { errorHandler: notify.onError "Error: <%= error.message %>" }
  .pipe pug()
  .pipe htmlbeautify()
  .pipe dest './dist/'
```
gulp4以前では、タスクに関数を登録して、タスクの関係性を管理する方法だったのですが、gulp４では関数のままでも受け取れる様になりました。
スッキリ書きやすいです。

pugの実行前にplumberでエラーになった際に、notifyにエラーを送ってタスクが落ちない様にしてあります。これがないと、ファイル更新でコンパイルエラーになった際にバックグランドで実行している自動コンパイルが停止してしまいます。

pugでｈｔｍｌに変換した後は、beautifyでインデントなどをきれいにしてもらってます。

## sass -> css

```coffeescript
css = -> 
  src './src/sass/*.sass'
  .pipe plumber　{ errorHandler: notify.onError　"Error: <%= error.message %>" }
  .pipe sass({includePaths:['node_modules/bootstrap/scss']})
  .pipe autoprefixer()　   # ベンダープレフィックスの付与
  .pipe sass { outputStyle: 'expanded' }
  .pipe dest './dist/css/'
```
pubとほとんど同じなんですが、bootstrapを読み込むのにincludePathsで指定しています。

## 自動コンパイル

```coffeescript
clean = ->
  del ['./dist/**', '!./dist']

watcher = (cb) ->
  watch './src/', (cb) ->
    clean()
    html()
    css()
    cb()
  cb()
```
ファイルの更新を監視して、更新があった場合は前回のコンパイル結果を全削除してコンパイルし直すという設定になっています。対象が大きくなるとこのやり方は重いと思いますが、しばらくは大丈夫です。

watcherはcallbackを引数に取ります。これは、次に説明するローカルサーバーの自動リロードと並列処理をするための条件です。ただこの書き方、おそらく間違っていて、watchの第２引数のcallbackに渡すのが良い気がするのですが・・・

## 自動リロード

```coffeescript
server = (cb) ->
  src './dist/'
  .pipe webserver {
    host: process.env.DEV_HOST || 'localhost',
    port: process.env.DEV_PORT || 8080,
    livereload: true
  }
  cb()
```
ローカルサーバーを立てて、更新がある場合自動でリロードしてくれます。ポートは指定がなければ8080ですが、実行時に`env DEV_PORT=8000 gulp`の様に指定すると他のポートで実行できます。

## デフォルトタスク
```coffeescript
exports.default = parallel [watcher, server]
```
watcherとserverはどちらも実行実行しっぱなしなので、並列で流す必要があります。

gulp4以前は、parallelを使わなくてもtaskに配列をわたせば処理してくれたのでその点は良かったのですが、その他の点では今の書き方のほうが気に入っています。

# 終わりに
参考にした記事のメモを忘れてしまいなんか申し訳無い感じです。
バックエンドエンジニアとしてはhtmlに内容が書いてあるのもあまりあまり気持ちがよくないので、今後はpugの機能をつかって切り離しをしたいです。