gulpを使って ファイルの徹底効率化をはかる

f:id:BOEL:20170919122430j:plain

HTMLでサイトを構築するとき、デザインや見栄え等をチェックすることはもちろんですが、
成果物をより良くするために、ソースやファイルにチューニングを加えることがあります。
HTML、CSSソースコード見直しや、整理、画像のファイル圧縮やHTMLのバリデーションチェック。 また、作る過程で要素が多くなったり、ページが増えたり、ヘッダーやフッターなど共通部分が何ページにも渡るケースがでてきます。
調整の過程で共通部分に修正が入ったとき、その部分に該当する全てのHTMLを編集して調整…などと言ったケースが発生することも稀ではありません。
テキストエディタで一括変換ができる場合もありますが、構造そのものに変更が入ったり、変更箇所が多岐に渡ると置換では要件を満たせないこともあります。
CMSフレームワークを入れるほどではないけど、柔軟なソース管理ができてかつ、面倒な手間を省きたいとき、gulpが役に立ちます。

 

gulpとは

Node.jsをベースとしたビルドツールです。
sassやcoffeescriptコンパイルなどを自動化するなどさまざまな手間を省いてくれるツールです。
ビルドの設定が簡単にカスタマイズできるため、いろんなプロジェクトに応じて臨機応変な対応できます。
設定のためのサンプルも、npm公式サイト(https://www.npmjs.com/)などを始め、第三者のデベロッパーが記事を載せているため、情報は比較的充実しています。

設定をJS構文で書くことになるため、多少難しいイメージがありますが、自分の目的さえはっきりしていればサンプルが見つかるため、すぐに設定することができます。
今回はWEB上の情報を集め、BOELで行う開発フローに当てはめて、
少々カスタマイズを加えながら設定をまとめていきます。

gulpをインストール

今回はmacの環境をベースに行っていきます。
macOS Sierra 10.12.6

node.jsをインストール

gulpを使うにはnode.jsのインストールが必要です。
下記サイトから実行ファイルがダウンロードできます。

https://nodejs.org/en/

アプリケーションをインストールする感覚で行えます。dmgを開き、手順に従ってインストールしてください。
node.jsをインストールした後、npmコマンドが実行できることを確認します。


npm -v
5.3.0

 

バージョンが出てくればインストールに問題ありません。

またnode.jsについては、TIPS「node.jsアプリをLinuxサーバーで公開してみよう」でも紹介しています。

そちらもぜひご覧ください。

 

グローバルインストール

gulpはグローバルインストール、ローカルインストール二通りが必要です。まずグローバルインストールを実行します。

 

sudo npm install gulp -g
 

プロジェクトフォルダ内にpackage.jsonが生成されているのを確認してください。

プロジェクトフォルダ内でgulpのローカルインストールを行います。

 

npm install --save-dev gulp

 

インストールが完了したらgulpが実行できるか確認しましょう。

ざっくりGulp.js入門(Mac向け)

http://qiita.com/kazukichi/items/884a1379eea5918689ed

gulpとかnpmのこととか

https://protean.cc/getting-started-with-gulp-and-npm

 

gulpの実行

gulpを実行するためにはgulpfile.jsというファイルが必要になります。
プロジェクトフォルダに作成しましょう。

 

gulpでプロジェクトの設定

設定を進めていきます。

基本的には下記サイトを参考にさせていただいています。これを軸に、プロジェクトの特性に合わせ調整を加えていきます。

 

EJSの基本 – EJSでサイト制作効率化

https://www.to-r.net/media/ejs-01/

gulp-ejsHTMLの共通部分を分割化

gulp-sassscssコンパイル

gulp-plumbergulp-notifyでエラー強制停止の防止を行う。リアルタイム通知

gulp-autoprefixerでベンダープレフィックスを自動で付与

gulp-webserverでローカルサーバーを立ち上げ。

 

※gulp-webserver

gulp-webserverで開発用Webサーバーを立ち上げる

http://labs.septeni.co.jp/entry/2015/10/26/233737

 

※gulp-plumbergulp-notify

これからはじめるGulp6):gulp-plumbergulp-notifyを使ったデスクトップ通知

https://whiskers.nukos.kitchen/2014/12/06/gulp-notify.html

 

追加で下記にも対応します。

imagemin-pngquantgulp-imageminで画像圧縮

gulp-html-validatorHTMLバリデーションする

 

参考サイトのサンプルとあわせて下記のようなコードになります。

 

//package.json
{
  "name": "ejs-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^3.1.1",
    "gulp-ejs": "^2.2.1",
    "gulp-html-validator": "^0.0.5",
    "gulp-imagemin": "^3.3.0",
    "gulp-notify": "^2.2.0",
    "gulp-plumber": "^1.1.0",
    "gulp-sass": "^3.0.0",
    "gulp-webserver": "^0.9.1",
    "imagemin-pngquant": "^5.0.1"
  }
}

-------------------------------------------

//gulpfile.js
const gulp = require('gulp');
const ejs = require('gulp-ejs');
const sass = require('gulp-sass');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const autoprefixer = require('gulp-autoprefixer');
const webserver = require('gulp-webserver');
const imagemin = require('gulp-imagemin');
const pngquant = require('imagemin-pngquant');
const htmlValidation = require('gulp-html-validator');


gulp.task('ejs',()=>{
return gulp.src("./src/ejs/*.ejs")
.pipe(plumber({errorHandler: notify.onError("Error: <%= error.message %>")}))
.pipe(ejs('', {"ext": ".html"}))
.pipe(gulp.dest("./dist"));
});

// sass
gulp.task('sass',()=>{
return gulp.src("./src/scss/*.scss")
.pipe(plumber({errorHandler: notify.onError("Error: <%= error.message %>")}))
.pipe(sass())
.pipe(autoprefixer({
browsers: ['last 2 versions'],
cascade: false
}))
.pipe(gulp.dest("./dist/css"));
});

// localhost
gulp.task('webserver', ()=>{
gulp.src("./dist")
.pipe(webserver({
host: 'localhost',
port: 8000,
livereload: true
}));
});


const imagePath = {
src: './src/images/',
dist: './dist/images/'
};

gulp.task('optimizeImage', ()=> {
return gulp.src(imagePath.src + '**/*').pipe(imagemin({
use: [
pngquant({
quality: 60 - 80,
speed: 1
})
]
})).pipe(gulp.dest(imagePath.dist));
});

gulp.task('valid', () =>{
return gulp.src("./dist/*.html")
.pipe(plumber({errorHandler: notify.onError("Error: <%= error.message %>")}))
.pipe(htmlValidation())
.pipe(gulp.dest('./validout'));
});

gulp.task('watch', ()=>{
gulp.watch('./src/scss/**/*.scss', ['sass']);
gulp.watch('./src/ejs/**/*.ejs', ['ejs']);
});

gulp.task('default',['watch','webserver','optimizeImage','valid']);

 

パッケージをインストールします。package.jsonを編集したら下記コマンドを実行します。

npm install

 

必要なパッケージが追加され、gulpfile.jsに書いた内容が実行できるようになります。
実際にどんなことができるか見ていきましょう。

 

ejsを軸にHTMLをテンプレート化

ejsではHTMLをテンプレート、分割化できます。
srcフォルダを作成し、パーツを作っていきます。

 

ejsフォルダを作成

index.ejs(コアファイル)を作成します。

 

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>構築のテスト</title>
</head>
<body>
<% include _partial/header %>
<main>
<p>テキストエリア</p>
</main>
<% include _partial/footer %>
</body>
</html>

 

ヘッダーとフッターを外部化

<% include _partial/header %>
<% include _partial/footer %>
これらはHTMLでは見覚えのない書き方です。 これはヘッダーとフッターのテンプレートを読み込む記述になります。
実際に_partialフォルダを作成し、header.ejsとfooter.ejsを作成します。

 

<!- header.ejs ->
<header>
外部化したヘッダーパーツ
</header>

-------------------------------------------

<!- footer.ejs ->
<footer>
外部化したフッターパーツ
</footer>

 

これでHTMLとなるファイルの準備はOKです。

scssのコンパイル

scssをコンパイルし、cssファイルにすることができます。
srcににscssのフォルダを用意し、scssのファイルを作成します。
下記のようにscssの形式で書いてみます。

 

/*common.scss*/
body{margin: 0;
p{margin: 0;}
}

 

画像の圧縮

gulpfile.jsには画像を圧縮する設定を行っています。
srcにimagesフォルダを作成し、画像を用意しておきます。

HTMLのバリデーション

生成されたHTMLのバリデーションを行った結果をファイルに書き出す設定をしています。
結果はvalidoutフォルダが自動生成され、その中に結果が表示されます。

gulpを実行してみる

上記の準備ができた段階でgulpを実行してみましょう。

 

gulp

 

distフォルダが自動生成され、成果物ファイルが構築されます。

 

<!- index.html ->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>構築のテスト</title>
</head>
<body>
<header>
外部化したヘッダーパーツ
</header>

<main>
<p>テキストエリア</p>
</main>
<footer>
外部化したフッターパーツ
</footer>

</body>
</html>

 

-------------------------------------------

/*common.css*/
body {
margin: 0; }
body p {
margin: 0; }

 

画像も生成されていることを確認します。
元の画像とファイルサイズを比較してみてください。
HTMLのプレビューを下記URLから確認することができます。
http://localhost:8000/

gulp実行中は上記URLからプレビュー閲覧すると、HTML、CSSを変更したときにブラウザがリフレッシュされ、リアルタイムで更新確認できます。

 

まとめ

以上gulpの基本的な使い方を実務ベースで構築してみました。
HTMLの外部分割化、scssの自動コンパイル、画像の圧縮、変更のリアルタイムプレビューなどひとつひとつ見ると細かい部分ではありますが試行、プレビューは制作の際に何度も繰り返す処理です。
小さいことでも積み重なれば、時間と労力を大きく節約することができます。
また、これらの設定はほんの一部の機能に過ぎず、他にもカスタマイズ方法は多々あります。
今度はプロジェクトにjsファイルもインクルードした想定でより使いやすくカスタマイズしていけたらと思います。

参考サイト
HTMLバリデーション

https://www.npmjs.com/package/gulp-html-validator

画像圧縮

http://blog.tsumikiinc.com/article/20150226_gulp-imagemin.html