本文へジャンプ

Gruntで効率化! リリース前の面倒な作業をまとめる

Posted by MD

納品時には、少しでもページを速く表示させるために、CSS・JS・画像の圧縮などファイルを最適化し、Webサイトを高速化することは必要不可欠です。
ファイルを圧縮するには、アプリを使ったりWebサービスを使ってもできますが、一つ一つ行うと時間がかかってしまいます。作業漏れの原因にもなります。

そこで、納品前の面倒な作業をGruntでまとめて行いたいと思います。Gruntを使うことによって、Sass(SCSS)のコンパイルHTMLの量産を簡単に出来たりするので、とても便利なツールです。事前にGruntのインストールと、SassとCompassのインストールを行ってから、ぜひ以下の手順でお試しください。

今回、Gruntでやることは下記の通りです。

  • HTMLファイルの圧縮
  • CSSファイルの圧縮
  • 画像ファイルの圧縮
  • JSファイル圧縮
  • 不要なファイル・フォルダの削除(Comassでスプライト画像を制作するためのフォルダ等)

※画像の圧縮にはImageOptim(Macのみ)を使用しますので、事前にアプリをダウンロードをしましょう。

構築環境について

Gruntを実行する上でのプロジェクトのフォルダ構成は、下記の通りです。

    project
    ├src              (Sass(SCSS)などのコンパイルして使うファイルのフォルダ)
    │└sass
    │ ├config.rb
    │ └style.scss
    │
    ├bin              (ローカルの作業フォルダ)
    │├index.html
    │├css
    │├js
    ││└sample.js
    │└images
    │ ├sprite.png
    │ └sprite           (Compassでスプライト画像を作るためのフォルダ。納品時は不要)
    │
    ├release          (サーバーにアップするフォルダ)
    │├index.html        (圧縮されたHTMLファイル)
    │├css               (圧縮されたCSSファイル)
    │├js
    ││└sample.js      (圧縮されたJSファイル)
    │└images
    │ └sprite.png       (スプライト画像のみ)
    ├package.json
    └Gruntfile.js
フォルダ分けをした理由
  • サーバーに不要なファイルをアップしないため
  • 圧縮前と圧縮後のファイルをローカル上に残しておくため
  • サーバーにアップするフォルダと作業ファイルを明確に分けるため

などのミスを防ぐためにフォルダを分けています。

Grunt - フォルダ分けをした理由

各フォルダの役割

srcフォルダ

コンパイルして使うファイル(Sass(SCSS)やCoffeeScriptなど)を置いています。

binフォルダ

ローカルでの作業フォルダになります。Compassを使ってスプライト画像を作るためのフォルダなども該当します。

releaseフォルダ

サーバーにアップするためのフォルダになります。このフォルダは、直接修正やファイルの追加などは行いません。

Gruntの設定

pakage.json

今回、使用するpackage.jsonになります。

    {
        "name": "Sample",
        "main": "Gruntfile.js",
        "dependencies": {
           "grunt": "~0.4.1"
         },
        "devDependencies": {
            "grunt-contrib-copy": "~0.4.1",
            "grunt-contrib-clean": "~0.5.0",
            "grunt-contrib-htmlmin": "~0.1.3",
            "grunt-contrib-cssmin": "~0.6.2",
            "grunt-contrib-uglify": "~0.2.4",
            "grunt-imageoptim": "~1.3.13",
            "grunt-contrib-livereload": "~0.1.2",
            "grunt-contrib-connect": "~0.5.0",
            "grunt-contrib-compass": "~0.6.0",
            "grunt-csscomb": "~0.5.0",
            "grunt-combine-media-queries": "~1.0.6",
            "grunt-contrib-watch": "~0.5.3"
        }
    }
納品ファイルを作成するためのモジュール
  • grunt-contrib-copy(ファイルのコピー)
  • grunt-contrib-clean(ファイルの削除)
  • grunt-contrib-htmlmin(HTMLファイルの圧縮)
  • grunt-contrib-cssmin(CSSファイルの圧縮)
  • grunt-contrib-uglify(JSファイルの圧縮)
  • grunt-imageoptim(イメージファイルの圧縮)
Sass(SCSS)をコンパイルするためのモジュール
  • grunt-contrib-livereload
  • grunt-contrib-connect
  • grunt-contrib-compass
  • grunt-csscomb
  • grunt-combine-media-queries
  • grunt-contrib-watch

上記の使い方はこちらの記事をご覧ください。

Gruntfile.js

今回使用したGruntfile.jsになります。

    'use strict';
    // livereload用の処理
    var
        path = require('path'),
        lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet,
        folderMount = function folderMount(connect, point) {
            return connect.static(path.resolve(point));
        };

    module.exports = function(grunt) {
        var pkg, taskName;
        pkg = grunt.file.readJSON('package.json');

        grunt.initConfig({
            pkg: pkg,
            dir: {
                src:'src',
                bin:'bin',
                release:'release',
                js: 'js',
                css: 'css',
                img:'images',
                sass:'sass'
            },
            // ファイルをコピーする
            copy: {
                html: {
                    expand: true,
                    // コピー元のディレクトリ
                    cwd: '<%= dir.bin %>/',
                    src: ['**/*.html'],
                    // コピー先のディレクトリ
                    dest: '<%= dir.release %>/'
                },
                css: {
                    expand: true,
                    cwd: '<%= dir.bin %>/',
                    src: ['css/**'],
                    dest: '<%= dir.release %>/'
                },
                images: {
                    expand: true,
                    cwd: '<%= dir.bin %>/',
                    src: ['images/**'],
                    dest: '<%= dir.release %>/'
                },
                js: {
                    expand: true,
                    cwd: '<%= dir.bin %>/',
                    src: ['js/**'],
                    dest: '<%= dir.release %>/'
                }
            },
            // HTMLを圧縮する
            htmlmin: {
                all: {
                    options: {
                        removeComments: true,
                        removeCommentsFromCDATA: true,
                        removeCDATASectionsFromCDATA: true,
                        collapseWhitespace: true,
                        removeRedundantAttributes: true,
                        removeOptionalTags: true
                    },
                    expand: true,
                    cwd: '<%= dir.bin %>/',
                    src: ['**/*.html'],
                    dest: '<%= dir.release %>/'
                }
            },
            // JSを圧縮する
            uglify: {
                min: {
                    expand: true,
                    cwd: '<%= dir.release %>/<%= dir.js %>/',
                    src: ['sample.js'],
                    dest: '<%= dir.release %>/<%= dir.js %>/'
                }
            },
            // CSSを圧縮する
            cssmin: {
                all: {
                    expand: true,
                    cwd: '<%= dir.bin %>/<%= dir.css %>/',
                    src: ['*.css'],
                    dest: '<%= dir.release %>/<%= dir.css %>/'
                }
            },
            // 画像を圧縮する
            imageoptim: {
                files: ['bin/'],
                options: {
                    jpegMini: true,
                    quitAfter: true
                }
            },
            // 不要なファイルを削除する
            clean: {
                // releaseフォルダ内を削除する
                deleteReleaseFolder: {
                    src: '<%= dir.release %>/'
                },
                // releaseから不要なファイルを削除する
                deleteReleaseFile: {
                    src: [
                        '<%= dir.release %>/<%= dir.img %>/sprite'
                    ],
                }
            },
            // localhostの設定
            // http://localhost:9001/で内容を確認することができます。
            connect: {
                livereload: {
                    options: {
                        port: 9001,
                        middleware: function(connect, options) {
                            return [lrSnippet, folderMount(connect, 'bin')];
                        }
                    }
                }
            },
            // Compassの設定
            compass: {
                dist: {
                    options: {
                        config: '<%= dir.src %>/<%= dir.sass %>/config.rb'
                    }
                }
            },
            // ファイルを監視する
            watch: {
                html: {
                    files: '<%= dir.bin %>/**/*.html',
                    tasks: [],
                    options: {
                        livereload: true,
                        nospawn: true
                    }
                },
                sass: {
                    files: ['<%= dir.src %>/<%= dir.sass %>/**'],
                    tasks: ['compass', 'cmq', 'csscomb'],
                    options: {
                        livereload: true,
                        nospawn: true
                    }
                }
            },
            // メディアクエリをまとめる
            cmq:{
                options: {
                    log: false
                },
                dev: {
                    files: {
                        '<%= dir.bin %>/<%= dir.css %>/': ['<%= dir.bin %>/<%= dir.css %>/style.css']
                    }
                }
            },
            // CSSのプロパティを揃える
            csscomb:{
                dev:{
                    expand: true,
                    cwd: '<%= dir.bin %>/<%= dir.css %>/',
                    src: ['*.css'],
                    dest: '<%= dir.bin %>/<%= dir.css %>/'
                }
            }
        });




        // pakage.jsonに記載されているパッケージを自動読み込み
        for(taskName in pkg.devDependencies) {
            if(taskName.substring(0, 6) == 'grunt-') {
                grunt.loadNpmTasks(taskName);
            }
        }

        // sassをコンパイルするgruntコマンド
        grunt.registerTask('default', ['connect', 'watch']);

        // 画像を圧縮するためのgruntコマンド
        grunt.registerTask('imgmin', ['imageoptim']);

        // 社内確認用のファイルを作るためのgruntコマンド
        grunt.registerTask('check', ['clean:deleteReleaseFolder', 'copy:html', 'copy:css', 'copy:images', 'copy:js', 'clean:deleteReleaseFile']);

        // 納品用のファイルを作るためのgruntコマンド
        grunt.registerTask('release', ['clean:deleteReleaseFolder', 'copy:images', 'copy:js', 'htmlmin', 'cssmin', 'uglify', 'clean:deleteReleaseFile']);

        grunt.registerTask('eatwarnings', function() {
            grunt.warn = grunt.fail.warn = function(warning) {
                grunt.log.error(warning);
            };
        });
    };

package.jsonとGruntfile.jsを準備して、モジュールをダウンロードします。

    sudo npm install

使用するコマンド

設定が完了したら、ターミナルからGruntfile.jsで設定したGruntのコマンドを実行します。今回使用するコマンドは下記の通りです。

    grunt imgmin    // 画像の圧縮
    grunt check     // 社内確認用のファイルを作成する
    grunt release   // サーバーアップ用のファイルを作成する

画像を圧縮するためのgruntコマンド

ImageOptimとJPEGminiを使用して、画像を圧縮します。コマンドを実行すると、ImageOptimとJPEGminiが立ち上がり画像が圧縮されます。処理が重いので、他のreleaseコマンドは別にしています。

コマンド
    grunt imgmin

filesで画像を圧縮するフォルダを指定します。jpegMiniがインストールされてない環境では、Gruntfile.jsのjpegMini: falseと設定します。

imageoptimタスクの設定
    imageoptim: {
        files: ['bin/'],
        options: {
            jpegMini: true,
            quitAfter: true
        }
    }

Grunt - imgmin

社内確認用のファイルを作るためのGruntコマンド

実行すると下記のタスクが実行されます。
社内でソースコードをチェックすることも有ると思うので、各種ファイルの圧縮を行いません。

  1. releaseフォルダを削除
  2. binフォルダからHTML, CSS, JS, Imageファイルをreleaseフォルダにコピー
  3. 不要なファイルをreleaseフォルダから削除
コマンド
    grunt check
削除するファイルの設定

削除ファイルの設定は、Gruntfile.jsのcleanタスク内のdeleteReleaseFileに不要なファイルやフォルダを追加していきます。

    clean: {
        // releaseフォルダ内を削除する
        deleteReleaseFolder: {
            src: '<%= dir.release %>/'
        },
        // releaseから不要なファイルを削除する
        deleteReleaseFile: {
            src: [
                '<%= dir.release %>/<%= dir.img %>/sprite',
                '削除するファイルやフォルダを指定してください'
            ],
        }
    }

Grunt - 削除対象の確認

納品用のファイルを作るためのgruntコマンド

実行すると下記のタスクが実行されます。納品用のファイルなので、HTML, CSS, JSファイルの圧縮も行います。

  1. releaseフォルダ中を削除
  2. binフォルダからJS, Imageファイルをコピー
  3. 圧縮したHTMLとCSSをreleaseフォルダに出力
  4. release/jsフォルダ内のJSファイルを圧縮
  5. 不要なファイルをreleaseフォルダから削除
コマンド
    grunt release

Grunt - 納品用のファイルを作る

まとめ

Gruntを使うと、納品時に必要な面倒な作業をまとめて行うことができます。自動化することによって、ファイルのアップミスやファイル最適化のし忘れなど、うっかりありがちなヒューマンエラーが減ります。

また、Gruntfile.jspackage.jsonだけを用意して、モジュールをインストール後に初期設定のコマンドを用意しておくと便利です。作業フォルダの作成や自分が使うSass(SCSS)ファイルのコピーなど、Gruntのコマンドだけで簡単に作業環境を作ることができます。gitやBowerなどのGruntのモジュールも出てるので、それらと連携した作業環境も構築することできます。

使いまわしを想定してベースとなるGruntfile.jsを作り、案件によって必要なタスクやモジュールを追加していくと良いと思います。

FRESHERS WANTED!
Recent Entries
MD EVENT REPORT
What's Hot?
日本各地の酒蔵との直取引により厳選して仕入れた日本酒を世界に販売
2018年度 新卒採用 Webデザイナー/エンジニア、プロデューサー/ディレクター募集
Movable Type AWS 移管&アップグレード サービス
SNS・ブログ・メールからの流入数が一目でわかる
こんな僕たちの仲間に入りませんか?
50,000円からのシネマグラフ(Cinemagraph)制作
TAKUYAが教えるギター・レッスン
KenKenが教えるベースギター教則アプリ
SNS連動型クチコミ拡散システム「レビュー ジェネレーター サービス」
1時間1万円の撮影スタジオ
Share this on
Facebook Twitter Google+ Tumblr