• 2017.9.15
  • Vol.78
  • WEB
  • Vol.78
  • WEB
  • 2017.9.15

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

HTMLでサイトを構築するとき、調整の過程で共通部分に修正が入って、 その部分に該当する全てのHTMLを編集して調整…などと言ったケースが発生することも稀ではありません。CMSやフレームワークを入れるほどではないけど、柔軟なソース管理ができて、面倒な手間を省きたいとき、 そんな時に役に立つgulpをご紹介します。

DEVELOPER

Y.M

gulpとは

gulpとは

Node.jsをベースとしたビルドツールです。
sassやcoffeescriptのコンパイルなどを自動化するなどさまざまな手間を省いてくれるツールです。
ビルドの設定が簡単にカスタマイズできるため、いろんなプロジェクトに応じて臨機応変な対応できます。
設定のためのサンプルも、npm公式サイトなどを始め、第三者のデベロッパーが記事を載せているため、情報は比較的充実しています。
設定をJS構文で書くことになるため、多少難しいイメージがありますが、自分の目的さえはっきりしていればサンプルが見つかるため、すぐに設定することができます。
今回はWEB上の情報を集め、BOELで行う開発フローに当てはめて、少々カスタマイズを加えながら設定をまとめていきます。

gulpをインストール

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

node.jsをインストール

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

Node.js

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

npm -v
5.3.0

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

またnode.jsについては、

「TIPS vol.63 node.jsアプリをLinuxサーバーで公開してみよう」 でも紹介しています。
そちらもぜひご覧ください。

グローバルインストール

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

sudo npm install gulp -g

プロジェクトフォルダ内にpackage.jsonが生成されているのを確認してください。
プロジェクトフォルダ内でgulpのローカルインストールを行います。

npm install --save-dev gulp

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

ざっくりGulp.js入門(Mac向け)
gulpとかnpmのこととか

gulpの実行

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

gulpでプロジェクトの設定

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

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

  • gulp-ejsでHTMLの共通部分を分割化
  • gulp-sassでscssをコンパイル
  • gulp-plumber、gulp-notifyでエラー強制停止の防止を行う。リアルタイム通知
  • gulp-autoprefixerでベンダープレフィックスを自動で付与
  • gulp-webserverでローカルサーバーを立ち上げ

 

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

※gulp-plumber、gulp-notify
これからはじめるGulp(6):gulp-plumberとgulp-notifyを使ったデスクトップ通知

追加で下記にも対応します。
・imagemin-pngquantとgulp-imageminで画像圧縮
・gulp-html-validatorでHTMLバリデーションする

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

//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から確認することができます。NPM公式サイト

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

まとめ

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

出典:HTMLバリデーション

出典:画像圧縮

TAGS

RECENT POSTS

TRENDING

INDEX

MORE FOR YOU

今日もあなたに気づきと発見がありますように

画面を回転してください | 株式会社BOEL

画面を回転してください